赞
踩
-
- class VM_GetStackTrace : public VM_Operation {
- private:
- JvmtiEnv *_env;
- JavaThread *_java_thread;
- jint _start_depth;
- jint _max_count;
- jvmtiFrameInfo *_frame_buffer;
- jint *_count_ptr;
- jvmtiError _result;
- public:
- VM_GetStackTrace(JvmtiEnv *env, JavaThread *java_thread,
- jint start_depth, jint max_count,
- jvmtiFrameInfo* frame_buffer, jint* count_ptr) {
- _env = env;
- _java_thread = java_thread;
- _start_depth = start_depth;
- _max_count = max_count;
- _frame_buffer = frame_buffer;
- _count_ptr = count_ptr;
- }
- jvmtiError result() { return _result; }
- VMOp_Type type() const { return VMOp_GetStackTrace; }
- void doit() {
- _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
- if (Threads::includes(_java_thread) && !_java_thread->is_exiting()
- && _java_thread->threadObj() != NULL) {
- _result = ((JvmtiEnvBase *)_env)->get_stack_trace(_java_thread,
- _start_depth, _max_count,
- _frame_buffer, _count_ptr);
- }
- }
- };
- struct StackInfoNode;
- class VM_GetMultipleStackTraces : public VM_Operation {
- private:
- JvmtiEnv *_env;
- jint _max_frame_count;
- jvmtiStackInfo *_stack_info;
- jvmtiError _result;
- int _frame_count_total;
- struct StackInfoNode *_head;
- JvmtiEnvBase *env() { return (JvmtiEnvBase *)_env; }
- jint max_frame_count() { return _max_frame_count; }
- struct StackInfoNode *head() { return _head; }
- void set_head(StackInfoNode *head) { _head = head; }
- protected:
- void set_result(jvmtiError result) { _result = result; }
- void fill_frames(jthread jt, JavaThread *thr, oop thread_oop);
- void allocate_and_fill_stacks(jint thread_count);
- public:
- VM_GetMultipleStackTraces(JvmtiEnv *env, jint max_frame_count) {
- _env = env;
- _max_frame_count = max_frame_count;
- _frame_count_total = 0;
- _head = NULL;
- _result = JVMTI_ERROR_NONE;
- }
- VMOp_Type type() const { return VMOp_GetMultipleStackTraces; }
- jvmtiStackInfo *stack_info() { return _stack_info; }
- jvmtiError result() { return _result; }
- };
- class VM_GetAllStackTraces : public VM_GetMultipleStackTraces {
- private:
- JavaThread *_calling_thread;
- jint _final_thread_count;
- public:
- VM_GetAllStackTraces(JvmtiEnv *env, JavaThread *calling_thread,
- jint max_frame_count)
- : VM_GetMultipleStackTraces(env, max_frame_count) {
- _calling_thread = calling_thread;
- }
- VMOp_Type type() const { return VMOp_GetAllStackTraces; }
- void doit();
- jint final_thread_count() { return _final_thread_count; }
- };
- class VM_GetThreadListStackTraces : public VM_GetMultipleStackTraces {
- private:
- jint _thread_count;
- const jthread* _thread_list;
- public:
- VM_GetThreadListStackTraces(JvmtiEnv *env, jint thread_count, const jthread* thread_list, jint max_frame_count)
- : VM_GetMultipleStackTraces(env, max_frame_count) {
- _thread_count = thread_count;
- _thread_list = thread_list;
- }
- VMOp_Type type() const { return VMOp_GetThreadListStackTraces; }
- void doit();
- };
- class VM_GetFrameCount : public VM_Operation {
- private:
- JvmtiEnv *_env;
- JvmtiThreadState *_state;
- jint *_count_ptr;
- jvmtiError _result;
- public:
- VM_GetFrameCount(JvmtiEnv *env, JvmtiThreadState *state, jint *count_ptr) {
- _env = env;
- _state = state;
- _count_ptr = count_ptr;
- }
- VMOp_Type type() const { return VMOp_GetFrameCount; }
- jvmtiError result() { return _result; }
- void doit() {
- _result = ((JvmtiEnvBase*)_env)->get_frame_count(_state, _count_ptr);
- }
- };
- class VM_GetFrameLocation : public VM_Operation {
- private:
- JvmtiEnv *_env;
- JavaThread* _java_thread;
- jint _depth;
- jmethodID* _method_ptr;
- jlocation* _location_ptr;
- jvmtiError _result;
- public:
- VM_GetFrameLocation(JvmtiEnv *env, JavaThread* java_thread, jint depth,
- jmethodID* method_ptr, jlocation* location_ptr) {
- _env = env;
- _java_thread = java_thread;
- _depth = depth;
- _method_ptr = method_ptr;
- _location_ptr = location_ptr;
- }
- VMOp_Type type() const { return VMOp_GetFrameLocation; }
- jvmtiError result() { return _result; }
- void doit() {
- _result = ((JvmtiEnvBase*)_env)->get_frame_location(_java_thread, _depth,
- _method_ptr, _location_ptr);
- }
- };
- class ResourceTracker : public StackObj {
- private:
- JvmtiEnv* _env;
- GrowableArray<unsigned char*> *_allocations;
- bool _failed;
- public:
- ResourceTracker(JvmtiEnv* env);
- ~ResourceTracker();
- jvmtiError allocate(jlong size, unsigned char** mem_ptr);
- unsigned char* allocate(jlong size);
- char* strdup(const char* str);
- };
- class JvmtiMonitorClosure: public MonitorClosure {
- private:
- JavaThread *_java_thread;
- JavaThread *_calling_thread;
- GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;
- jvmtiError _error;
- JvmtiEnvBase *_env;
- public:
- JvmtiMonitorClosure(JavaThread* thread, JavaThread *calling_thread,
- GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors,
- JvmtiEnvBase *env) {
- _java_thread = thread;
- _calling_thread = calling_thread;
- _owned_monitors_list = owned_monitors;
- _error = JVMTI_ERROR_NONE;
- _env = env;
- }
- void do_monitor(ObjectMonitor* mon);
- jvmtiError error() { return _error;}
- };
- #endif // SHARE_VM_PRIMS_JVMTIENVBASE_HPP
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiEnvFill.java
- import java.io.*;
- import java.util.*;
- class jvmtiEnvFill {
- public static void main(String[] args) throws IOException {
- if (args.length != 3) {
- System.err.println("usage: <filledFile> <stubFile> <resultFile>");
- System.exit(1);
- }
- String filledFN = args[0];
- String stubFN = args[1];
- String resultFN = args[2];
- SourceFile filledSF = new SourceFile(filledFN);
- SourceFile stubSF = new SourceFile(stubFN);
- stubSF.fill(filledSF);
- PrintWriter out = new PrintWriter(new FileWriter(resultFN));
- stubSF.output(out);
- out.close();
- }
- }
- class SourceFile {
- static final String endFilePrefix = "// end file prefix";
- static final String functionPrefix = "JvmtiEnv::";
- final String fn;
- LineNumberReader in;
- String line;
- List<String> top = new ArrayList<String>();
- List<String> before = new ArrayList<String>();
- boolean inFilePrefix = true;
- List<Function> functions = new ArrayList<Function>();
- Map<String, Function> functionMap = new HashMap<String, Function>();
- class Function {
- String name;
- String args;
- String compareArgs;
- List comment;
- List<String> body = new ArrayList<String>();
- Function() throws IOException {
- line = in.readLine();
- String trimmed = line.trim();
- if (!trimmed.startsWith(functionPrefix)) {
- error("expected '" + functionPrefix + "'");
- }
- int index = trimmed.indexOf('(', functionPrefix.length());
- if (index == -1) {
- error("missing open paren");
- }
- name = trimmed.substring(functionPrefix.length(), index);
- int index2 = trimmed.indexOf(')', index);
- if (index2 == -1) {
- error("missing close paren - must be on same line");
- }
- args = trimmed.substring(index+1, index2);
- compareArgs = args.replaceAll("\\s", "");
- String tail = trimmed.substring(index2+1).trim();
- if (!tail.equals("{")) {
- error("function declaration first line must end with open bracket '{', instead got '" +
- tail + "'");
- }
- while(true) {
- line = in.readLine();
- if (line == null) {
- line = ""; // so error does not look wierd
- error("unexpected end of file");
- }
- if (line.startsWith("}")) {
- break;
- }
- body.add(line);
- }
- String expected = "} /* end " + name + " */";
- trimmed = line.replaceAll("\\s","");
- if (!trimmed.equals(expected.replaceAll("\\s",""))) {
- error("function end is malformed - should be: " + expected);
- }
- comment = before;
- before = new ArrayList<String>();
- }
- void remove() {
- functionMap.remove(name);
- }
- String fileName() {
- return fn;
- }
- void fill(Function filledFunc) {
- if (filledFunc == null) {
- System.err.println("Warning: function " + name + " missing from filled file");
- body.add(0, " /*** warning: function added and not filled in ***/");
- } else {
- int fbsize = filledFunc.body.size();
- int bsize = body.size();
- if (fbsize > bsize || !body.subList(bsize-fbsize,bsize).equals(filledFunc.body)) {
- body = filledFunc.body;
- if (!compareArgs.equals(filledFunc.compareArgs)) {
- System.err.println("Warning: function " + name +
- ": filled and stub arguments differ");
- System.err.println(" old (filled): " + filledFunc.args);
- System.err.println(" new (stub): " + args);
- body.add(0, " /*** warning: arguments changed, were: " +
- filledFunc.args + " ***/");
- }
- }
- filledFunc.remove(); // mark used
- }
- }
- void output(PrintWriter out) {
- Iterator it = comment.iterator();
- while (it.hasNext()) {
- out.println(it.next());
- }
- out.println("jvmtiError");
- out.print(functionPrefix);
- out.print(name);
- out.print('(');
- out.print(args);
- out.println(") {");
- it = body.iterator();
- while (it.hasNext()) {
- out.println(it.next());
- }
- out.print("} /* end ");
- out.print(name);
- out.println(" */");
- }
- }
- SourceFile(String fn) throws IOException {
- this.fn = fn;
- Reader reader = new FileReader(fn);
- in = new LineNumberReader(reader);
- while (readGaps()) {
- Function func = new Function();
- functionMap.put(func.name, func);
- functions.add(func);
- }
- in.close();
- }
- void error(String msg) {
- System.err.println("Fatal error parsing file: " + fn);
- System.err.println("Line number: " + in.getLineNumber());
- System.err.println("Error message: " + msg);
- System.err.println("Source line: " + line);
- System.exit(1);
- }
- boolean readGaps() throws IOException {
- while(true) {
- line = in.readLine();
- if (line == null) {
- return false; // end of file
- }
- if (!inFilePrefix && line.startsWith("}")) {
- error("unexpected close bracket in first column, outside of function.\n");
- }
- String trimmed = line.trim();
- if (line.startsWith("jvmtiError")) {
- if (trimmed.equals("jvmtiError")) {
- if (inFilePrefix) {
- error("unexpected 'jvmtiError' line in file prefix.\n" +
- "is '" + endFilePrefix + "'... line missing?");
- }
- return true; // beginning of a function
- } else {
- error("extra characters at end of 'jvmtiError'");
- }
- }
- if (inFilePrefix) {
- top.add(line);
- } else {
- trimmed = line.trim();
- if (!trimmed.equals("") && !trimmed.startsWith("//") && !trimmed.startsWith("#")) {
- error("only comments and blank lines allowed between functions");
- }
- before.add(line);
- }
- if (line.replaceAll("\\s","").toLowerCase().startsWith(endFilePrefix.replaceAll("\\s",""))) {
- if (!inFilePrefix) {
- error("excess '" + endFilePrefix + "'");
- }
- inFilePrefix = false;
- }
- }
- }
- void fill(SourceFile filledSF) {
- top = filledSF.top;
- Iterator it = functions.iterator();
- while (it.hasNext()) {
- Function stubFunc = (Function)(it.next());
- Function filledFunc = (Function)filledSF.functionMap.get(stubFunc.name);
- stubFunc.fill(filledFunc);
- }
- if (filledSF.functionMap.size() > 0) {
- System.err.println("Warning: the following functions were present in the " +
- "filled file but missing in the stub file and thus not copied:");
- it = filledSF.functionMap.values().iterator();
- while (it.hasNext()) {
- System.err.println(" " + ((Function)(it.next())).name);
- }
- }
- }
- void output(PrintWriter out) {
- Iterator it = top.iterator();
- while (it.hasNext()) {
- out.println(it.next());
- }
- it = functions.iterator();
- while (it.hasNext()) {
- Function stubFunc = (Function)(it.next());
- stubFunc.output(out);
- }
- }
- }
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiEnvThreadState.cpp
- #include "precompiled.hpp"
- #include "classfile/systemDictionary.hpp"
- #include "interpreter/interpreter.hpp"
- #include "jvmtifiles/jvmtiEnv.hpp"
- #include "memory/resourceArea.hpp"
- #include "prims/jvmtiEnvThreadState.hpp"
- #include "prims/jvmtiEventController.inline.hpp"
- #include "prims/jvmtiImpl.hpp"
- #include "runtime/handles.hpp"
- #include "runtime/handles.inline.hpp"
- #include "runtime/interfaceSupport.hpp"
- #include "runtime/javaCalls.hpp"
- #include "runtime/signature.hpp"
- #include "runtime/vframe.hpp"
- #include "runtime/vm_operations.hpp"
- #ifndef PRODUCT
- void JvmtiFramePop::print() {
- tty->print_cr("_frame_number=%d", _frame_number);
- }
- #endif
- void
- JvmtiFramePops::set(JvmtiFramePop& fp) {
- if (_pops->find(fp.frame_number()) < 0) {
- _pops->append(fp.frame_number());
- }
- }
- void
- JvmtiFramePops::clear(JvmtiFramePop& fp) {
- assert(_pops->length() > 0, "No more frame pops");
- _pops->remove(fp.frame_number());
- }
- int
- JvmtiFramePops::clear_to(JvmtiFramePop& fp) {
- int cleared = 0;
- int index = 0;
- while (index < _pops->length()) {
- JvmtiFramePop pop = JvmtiFramePop(_pops->at(index));
- if (pop.above_on_stack(fp)) {
- _pops->remove_at(index);
- ++cleared;
- } else {
- ++index;
- }
- }
- return cleared;
- }
- JvmtiFramePops::JvmtiFramePops() {
- _pops = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int> (2, true);
- }
- JvmtiFramePops::~JvmtiFramePops() {
- delete _pops;
- }
- #ifndef PRODUCT
- void JvmtiFramePops::print() {
- ResourceMark rm;
- int n = _pops->length();
- for (int i=0; i<n; i++) {
- JvmtiFramePop fp = JvmtiFramePop(_pops->at(i));
- tty->print("%d: ", i);
- fp.print();
- tty->cr();
- }
- }
- #endif
- JvmtiEnvThreadState::JvmtiEnvThreadState(JavaThread *thread, JvmtiEnvBase *env) :
- _event_enable() {
- _thread = thread;
- _env = (JvmtiEnv*)env;
- _next = NULL;
- _frame_pops = NULL;
- _current_bci = 0;
- _current_method_id = NULL;
- _breakpoint_posted = false;
- _single_stepping_posted = false;
- _agent_thread_local_storage_data = NULL;
- }
- JvmtiEnvThreadState::~JvmtiEnvThreadState() {
- delete _frame_pops;
- _frame_pops = NULL;
- }
- void JvmtiEnvThreadState::compare_and_set_current_location(Method* new_method,
- address new_location, jvmtiEvent event) {
- int new_bci = new_location - new_method->code_base();
- jmethodID new_method_id = new_method->jmethod_id();
- if (_current_bci == new_bci && _current_method_id == new_method_id) {
- switch (event) {
- case JVMTI_EVENT_BREAKPOINT:
- _breakpoint_posted = _breakpoint_posted && _single_stepping_posted;
- break;
- case JVMTI_EVENT_SINGLE_STEP:
- _single_stepping_posted = true;
- break;
- default:
- assert(false, "invalid event value passed");
- break;
- }
- return;
- }
- set_current_location(new_method_id, new_bci);
- _breakpoint_posted = false;
- _single_stepping_posted = false;
- }
- JvmtiFramePops* JvmtiEnvThreadState::get_frame_pops() {
- #ifdef ASSERT
- uint32_t debug_bits = 0;
- #endif
- assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
- "frame pop data only accessible from same thread or while suspended");
- if (_frame_pops == NULL) {
- _frame_pops = new JvmtiFramePops();
- assert(_frame_pops != NULL, "_frame_pops != NULL");
- }
- return _frame_pops;
- }
- bool JvmtiEnvThreadState::has_frame_pops() {
- return _frame_pops == NULL? false : (_frame_pops->length() > 0);
- }
- void JvmtiEnvThreadState::set_frame_pop(int frame_number) {
- #ifdef ASSERT
- uint32_t debug_bits = 0;
- #endif
- assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
- "frame pop data only accessible from same thread or while suspended");
- JvmtiFramePop fpop(frame_number);
- JvmtiEventController::set_frame_pop(this, fpop);
- }
- void JvmtiEnvThreadState::clear_frame_pop(int frame_number) {
- #ifdef ASSERT
- uint32_t debug_bits = 0;
- #endif
- assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
- "frame pop data only accessible from same thread or while suspended");
- JvmtiFramePop fpop(frame_number);
- JvmtiEventController::clear_frame_pop(this, fpop);
- }
- void JvmtiEnvThreadState::clear_to_frame_pop(int frame_number) {
- #ifdef ASSERT
- uint32_t debug_bits = 0;
- #endif
- assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
- "frame pop data only accessible from same thread or while suspended");
- JvmtiFramePop fpop(frame_number);
- JvmtiEventController::clear_to_frame_pop(this, fpop);
- }
- bool JvmtiEnvThreadState::is_frame_pop(int cur_frame_number) {
- #ifdef ASSERT
- uint32_t debug_bits = 0;
- #endif
- assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
- "frame pop data only accessible from same thread or while suspended");
- if (!get_thread()->is_interp_only_mode() || _frame_pops == NULL) {
- return false;
- }
- JvmtiFramePop fp(cur_frame_number);
- return get_frame_pops()->contains(fp);
- }
- class VM_GetCurrentLocation : public VM_Operation {
- private:
- JavaThread *_thread;
- jmethodID _method_id;
- int _bci;
- public:
- VM_GetCurrentLocation(JavaThread *thread) {
- _thread = thread;
- }
- VMOp_Type type() const { return VMOp_GetCurrentLocation; }
- void doit() {
- ResourceMark rmark; // _thread != Thread::current()
- RegisterMap rm(_thread, false);
- if (!_thread->is_exiting() && _thread->has_last_Java_frame()) {
- javaVFrame* vf = _thread->last_java_vframe(&rm);
- assert(vf != NULL, "must have last java frame");
- Method* method = vf->method();
- _method_id = method->jmethod_id();
- _bci = vf->bci();
- } else {
- _method_id = (jmethodID)NULL;
- _bci = 0;
- }
- }
- void get_current_location(jmethodID *method_id, int *bci) {
- }
- };
- void JvmtiEnvThreadState::reset_current_location(jvmtiEvent event_type, bool enabled) {
- assert(event_type == JVMTI_EVENT_SINGLE_STEP || event_type == JVMTI_EVENT_BREAKPOINT,
- "must be single-step or breakpoint event");
- if (enabled) {
- if (event_type == JVMTI_EVENT_SINGLE_STEP && _thread->has_last_Java_frame()) {
- jmethodID method_id;
- int bci;
- VM_GetCurrentLocation op(_thread);
- VMThread::execute(&op);
- op.get_current_location(&method_id, &bci);
- set_current_location(method_id, bci);
- }
- } else if (event_type == JVMTI_EVENT_SINGLE_STEP || !is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
- clear_current_location();
- }
- }
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiEnvThreadState.hpp
- #ifndef SHARE_VM_PRIMS_JVMTIENVTHREADSTATE_HPP
- #define SHARE_VM_PRIMS_JVMTIENVTHREADSTATE_HPP
- #include "jvmtifiles/jvmti.h"
- #include "memory/allocation.hpp"
- #include "memory/allocation.inline.hpp"
- #include "oops/instanceKlass.hpp"
- #include "prims/jvmtiEventController.hpp"
- #include "utilities/globalDefinitions.hpp"
- #include "utilities/growableArray.hpp"
- class JvmtiEnv;
- class JvmtiFramePop VALUE_OBJ_CLASS_SPEC {
- private:
- int _frame_number;
- public:
- JvmtiFramePop() {}
- JvmtiFramePop(int frame_number) {
- assert(frame_number >= 0, "invalid frame number");
- _frame_number = frame_number;
- }
- int frame_number() { return _frame_number; }
- int above_on_stack(JvmtiFramePop& other) { return _frame_number > other._frame_number; }
- void print() PRODUCT_RETURN;
- };
- class JvmtiFramePops : public CHeapObj<mtInternal> {
- private:
- GrowableArray<int>* _pops;
- friend class JvmtiEventControllerPrivate;
- void set(JvmtiFramePop& fp);
- void clear(JvmtiFramePop& fp);
- int clear_to(JvmtiFramePop& fp);
- public:
- JvmtiFramePops();
- ~JvmtiFramePops();
- bool contains(JvmtiFramePop& fp) { return _pops->contains(fp.frame_number()); }
- int length() { return _pops->length(); }
- void print() PRODUCT_RETURN;
- };
- class JvmtiEnvThreadState : public CHeapObj<mtInternal> {
- private:
- friend class JvmtiEnv;
- JavaThread *_thread;
- JvmtiEnv *_env;
- JvmtiEnvThreadState *_next;
- jmethodID _current_method_id;
- int _current_bci;
- bool _breakpoint_posted;
- bool _single_stepping_posted;
- JvmtiEnvThreadEventEnable _event_enable;
- void *_agent_thread_local_storage_data; // per env and per thread agent allocated data.
- JvmtiFramePops *_frame_pops;
- inline void set_current_location(jmethodID method_id, int bci) {
- _current_method_id = method_id;
- _current_bci = bci;
- }
- friend class JvmtiEnvThreadStateIterator;
- JvmtiEnvThreadState* next() { return _next; }
- friend class JvmtiThreadState;
- void set_next(JvmtiEnvThreadState* link) { _next = link; }
- public:
- JvmtiEnvThreadState(JavaThread *thread, JvmtiEnvBase *env);
- ~JvmtiEnvThreadState();
- bool is_enabled(jvmtiEvent event_type) { return _event_enable.is_enabled(event_type); }
- JvmtiEnvThreadEventEnable *event_enable() { return &_event_enable; }
- void *get_agent_thread_local_storage_data() { return _agent_thread_local_storage_data; }
- void set_agent_thread_local_storage_data (void *data) { _agent_thread_local_storage_data = data; }
- void compare_and_set_current_location(Method* method, address location, jvmtiEvent event);
- void clear_current_location() { set_current_location((jmethodID)NULL, 0); }
- void reset_current_location(jvmtiEvent event, bool enabled);
- inline void set_breakpoint_posted() { _breakpoint_posted = true; }
- inline void set_single_stepping_posted() {
- _single_stepping_posted = true;
- }
- inline bool breakpoint_posted() { return _breakpoint_posted; }
- inline bool single_stepping_posted() {
- return _single_stepping_posted;
- }
- inline JavaThread *get_thread() { return _thread; }
- inline JvmtiEnv *get_env() { return _env; }
- JvmtiFramePops* get_frame_pops();
- bool has_frame_pops();
- bool is_frame_pop(int cur_stack_depth);
- void set_frame_pop(int frame_number);
- void clear_frame_pop(int frame_number);
- void clear_to_frame_pop(int frame_number);
- };
- #endif // SHARE_VM_PRIMS_JVMTIENVTHREADSTATE_HPP
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiEventController.cpp
- #include "precompiled.hpp"
- #include "interpreter/interpreter.hpp"
- #include "jvmtifiles/jvmtiEnv.hpp"
- #include "memory/resourceArea.hpp"
- #include "prims/jvmtiEventController.hpp"
- #include "prims/jvmtiEventController.inline.hpp"
- #include "prims/jvmtiExport.hpp"
- #include "prims/jvmtiImpl.hpp"
- #include "prims/jvmtiThreadState.inline.hpp"
- #include "runtime/frame.hpp"
- #include "runtime/thread.hpp"
- #include "runtime/vframe.hpp"
- #include "runtime/vframe_hp.hpp"
- #include "runtime/vmThread.hpp"
- #include "runtime/vm_operations.hpp"
- PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
- #ifdef JVMTI_TRACE
- #define EC_TRACE(out) do { \
- if (JvmtiTrace::trace_event_controller()) { \
- SafeResourceMark rm; \
- tty->print_cr out; \
- } \
- } while (0)
- #else
- #define EC_TRACE(out)
- #endif /*JVMTI_TRACE */
- static const jlong SINGLE_STEP_BIT = (((jlong)1) << (JVMTI_EVENT_SINGLE_STEP - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong FRAME_POP_BIT = (((jlong)1) << (JVMTI_EVENT_FRAME_POP - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong BREAKPOINT_BIT = (((jlong)1) << (JVMTI_EVENT_BREAKPOINT - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong FIELD_ACCESS_BIT = (((jlong)1) << (JVMTI_EVENT_FIELD_ACCESS - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong FIELD_MODIFICATION_BIT = (((jlong)1) << (JVMTI_EVENT_FIELD_MODIFICATION - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong METHOD_ENTRY_BIT = (((jlong)1) << (JVMTI_EVENT_METHOD_ENTRY - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong METHOD_EXIT_BIT = (((jlong)1) << (JVMTI_EVENT_METHOD_EXIT - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong CLASS_FILE_LOAD_HOOK_BIT = (((jlong)1) << (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong NATIVE_METHOD_BIND_BIT = (((jlong)1) << (JVMTI_EVENT_NATIVE_METHOD_BIND - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong VM_START_BIT = (((jlong)1) << (JVMTI_EVENT_VM_START - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong VM_INIT_BIT = (((jlong)1) << (JVMTI_EVENT_VM_INIT - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong VM_DEATH_BIT = (((jlong)1) << (JVMTI_EVENT_VM_DEATH - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong CLASS_LOAD_BIT = (((jlong)1) << (JVMTI_EVENT_CLASS_LOAD - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong CLASS_PREPARE_BIT = (((jlong)1) << (JVMTI_EVENT_CLASS_PREPARE - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong THREAD_START_BIT = (((jlong)1) << (JVMTI_EVENT_THREAD_START - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong THREAD_END_BIT = (((jlong)1) << (JVMTI_EVENT_THREAD_END - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong EXCEPTION_THROW_BIT = (((jlong)1) << (JVMTI_EVENT_EXCEPTION - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong EXCEPTION_CATCH_BIT = (((jlong)1) << (JVMTI_EVENT_EXCEPTION_CATCH - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong MONITOR_CONTENDED_ENTER_BIT = (((jlong)1) << (JVMTI_EVENT_MONITOR_CONTENDED_ENTER - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong MONITOR_CONTENDED_ENTERED_BIT = (((jlong)1) << (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong MONITOR_WAIT_BIT = (((jlong)1) << (JVMTI_EVENT_MONITOR_WAIT - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong MONITOR_WAITED_BIT = (((jlong)1) << (JVMTI_EVENT_MONITOR_WAITED - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong DYNAMIC_CODE_GENERATED_BIT = (((jlong)1) << (JVMTI_EVENT_DYNAMIC_CODE_GENERATED - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong DATA_DUMP_BIT = (((jlong)1) << (JVMTI_EVENT_DATA_DUMP_REQUEST - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong COMPILED_METHOD_LOAD_BIT = (((jlong)1) << (JVMTI_EVENT_COMPILED_METHOD_LOAD - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong COMPILED_METHOD_UNLOAD_BIT = (((jlong)1) << (JVMTI_EVENT_COMPILED_METHOD_UNLOAD - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong GARBAGE_COLLECTION_START_BIT = (((jlong)1) << (JVMTI_EVENT_GARBAGE_COLLECTION_START - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong GARBAGE_COLLECTION_FINISH_BIT = (((jlong)1) << (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong OBJECT_FREE_BIT = (((jlong)1) << (JVMTI_EVENT_OBJECT_FREE - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong RESOURCE_EXHAUSTED_BIT = (((jlong)1) << (JVMTI_EVENT_RESOURCE_EXHAUSTED - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong VM_OBJECT_ALLOC_BIT = (((jlong)1) << (JVMTI_EVENT_VM_OBJECT_ALLOC - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong CLASS_UNLOAD_BIT = (((jlong)1) << (EXT_EVENT_CLASS_UNLOAD - TOTAL_MIN_EVENT_TYPE_VAL));
- static const jlong MONITOR_BITS = MONITOR_CONTENDED_ENTER_BIT | MONITOR_CONTENDED_ENTERED_BIT |
- MONITOR_WAIT_BIT | MONITOR_WAITED_BIT;
- static const jlong EXCEPTION_BITS = EXCEPTION_THROW_BIT | EXCEPTION_CATCH_BIT;
- static const jlong INTERP_EVENT_BITS = SINGLE_STEP_BIT | METHOD_ENTRY_BIT | METHOD_EXIT_BIT |
- FRAME_POP_BIT | FIELD_ACCESS_BIT | FIELD_MODIFICATION_BIT;
- static const jlong THREAD_FILTERED_EVENT_BITS = INTERP_EVENT_BITS | EXCEPTION_BITS | MONITOR_BITS |
- BREAKPOINT_BIT | CLASS_LOAD_BIT | CLASS_PREPARE_BIT | THREAD_END_BIT;
- static const jlong NEED_THREAD_LIFE_EVENTS = THREAD_FILTERED_EVENT_BITS | THREAD_START_BIT;
- static const jlong EARLY_EVENT_BITS = CLASS_FILE_LOAD_HOOK_BIT |
- VM_START_BIT | VM_INIT_BIT | VM_DEATH_BIT | NATIVE_METHOD_BIND_BIT |
- THREAD_START_BIT | THREAD_END_BIT |
- DYNAMIC_CODE_GENERATED_BIT;
- static const jlong GLOBAL_EVENT_BITS = ~THREAD_FILTERED_EVENT_BITS;
- static const jlong SHOULD_POST_ON_EXCEPTIONS_BITS = EXCEPTION_BITS | METHOD_EXIT_BIT | FRAME_POP_BIT;
- JvmtiEventEnabled::JvmtiEventEnabled() {
- clear();
- }
- void JvmtiEventEnabled::clear() {
- _enabled_bits = 0;
- #ifndef PRODUCT
- _init_guard = JEE_INIT_GUARD;
- #endif
- }
- void JvmtiEventEnabled::set_enabled(jvmtiEvent event_type, bool enabled) {
- jlong bits = get_bits();
- jlong mask = bit_for(event_type);
- if (enabled) {
- bits |= mask;
- } else {
- bits &= ~mask;
- }
- set_bits(bits);
- }
- JvmtiEnvThreadEventEnable::JvmtiEnvThreadEventEnable() {
- _event_user_enabled.clear();
- _event_enabled.clear();
- }
- JvmtiEnvThreadEventEnable::~JvmtiEnvThreadEventEnable() {
- _event_user_enabled.clear();
- _event_enabled.clear();
- }
- JvmtiThreadEventEnable::JvmtiThreadEventEnable() {
- _event_enabled.clear();
- }
- JvmtiThreadEventEnable::~JvmtiThreadEventEnable() {
- _event_enabled.clear();
- }
- JvmtiEnvEventEnable::JvmtiEnvEventEnable() {
- _event_user_enabled.clear();
- _event_callback_enabled.clear();
- _event_enabled.clear();
- }
- JvmtiEnvEventEnable::~JvmtiEnvEventEnable() {
- _event_user_enabled.clear();
- _event_callback_enabled.clear();
- _event_enabled.clear();
- }
- class VM_EnterInterpOnlyMode : public VM_Operation {
- private:
- JvmtiThreadState *_state;
- public:
- VM_EnterInterpOnlyMode(JvmtiThreadState *state);
- bool allow_nested_vm_operations() const { return true; }
- VMOp_Type type() const { return VMOp_EnterInterpOnlyMode; }
- void doit();
- bool can_be_deoptimized(vframe* vf) {
- return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized());
- }
- };
- VM_EnterInterpOnlyMode::VM_EnterInterpOnlyMode(JvmtiThreadState *state)
- : _state(state)
- {
- }
- void VM_EnterInterpOnlyMode::doit() {
- _state->invalidate_cur_stack_depth();
- _state->enter_interp_only_mode();
- JavaThread *thread = _state->get_thread();
- if (thread->has_last_Java_frame()) {
- int num_marked = 0;
- ResourceMark resMark;
- RegisterMap rm(thread, false);
- for (vframe* vf = thread->last_java_vframe(&rm); vf; vf = vf->sender()) {
- if (can_be_deoptimized(vf)) {
- ((compiledVFrame*) vf)->code()->mark_for_deoptimization();
- ++num_marked;
- }
- }
- if (num_marked > 0) {
- VM_Deoptimize op;
- VMThread::execute(&op);
- }
- }
- }
- class VM_ChangeSingleStep : public VM_Operation {
- private:
- bool _on;
- public:
- VM_ChangeSingleStep(bool on);
- VMOp_Type type() const { return VMOp_ChangeSingleStep; }
- bool allow_nested_vm_operations() const { return true; }
- void doit(); // method definition is after definition of JvmtiEventControllerPrivate because of scoping
- };
- VM_ChangeSingleStep::VM_ChangeSingleStep(bool on)
- : _on(on != 0)
- {
- }
- class JvmtiEventControllerPrivate : public AllStatic {
- static bool _initialized;
- public:
- static void set_should_post_single_step(bool on);
- static void enter_interp_only_mode(JvmtiThreadState *state);
- static void leave_interp_only_mode(JvmtiThreadState *state);
- static void recompute_enabled();
- static jlong recompute_env_enabled(JvmtiEnvBase* env);
- static jlong recompute_env_thread_enabled(JvmtiEnvThreadState* ets, JvmtiThreadState* state);
- static jlong recompute_thread_enabled(JvmtiThreadState *state);
- static void event_init();
- static void set_user_enabled(JvmtiEnvBase *env, JavaThread *thread,
- jvmtiEvent event_type, bool enabled);
- static void set_event_callbacks(JvmtiEnvBase *env,
- const jvmtiEventCallbacks* callbacks,
- jint size_of_callbacks);
- static void set_extension_event_callback(JvmtiEnvBase *env,
- jint extension_event_index,
- jvmtiExtensionEvent callback);
- static void set_frame_pop(JvmtiEnvThreadState *env_thread, JvmtiFramePop fpop);
- static void clear_frame_pop(JvmtiEnvThreadState *env_thread, JvmtiFramePop fpop);
- static void clear_to_frame_pop(JvmtiEnvThreadState *env_thread, JvmtiFramePop fpop);
- static void change_field_watch(jvmtiEvent event_type, bool added);
- static void thread_started(JavaThread *thread);
- static void thread_ended(JavaThread *thread);
- static void env_initialize(JvmtiEnvBase *env);
- static void env_dispose(JvmtiEnvBase *env);
- static void vm_start();
- static void vm_init();
- static void vm_death();
- static void trace_changed(JvmtiThreadState *state, jlong now_enabled, jlong changed);
- static void trace_changed(jlong now_enabled, jlong changed);
- };
- bool JvmtiEventControllerPrivate::_initialized = false;
- void JvmtiEventControllerPrivate::set_should_post_single_step(bool on) {
- JvmtiExport::set_should_post_single_step(on);
- }
- void VM_ChangeSingleStep::doit() {
- JvmtiEventControllerPrivate::set_should_post_single_step(_on);
- if (_on) {
- Interpreter::notice_safepoints();
- }
- }
- void JvmtiEventControllerPrivate::enter_interp_only_mode(JvmtiThreadState *state) {
- EC_TRACE(("JVMTI [%s] # Entering interpreter only mode",
- JvmtiTrace::safe_get_thread_name(state->get_thread())));
- VM_EnterInterpOnlyMode op(state);
- VMThread::execute(&op);
- }
- void
- JvmtiEventControllerPrivate::leave_interp_only_mode(JvmtiThreadState *state) {
- EC_TRACE(("JVMTI [%s] # Leaving interpreter only mode",
- JvmtiTrace::safe_get_thread_name(state->get_thread())));
- state->leave_interp_only_mode();
- }
- void
- JvmtiEventControllerPrivate::trace_changed(JvmtiThreadState *state, jlong now_enabled, jlong changed) {
- #ifdef JVMTI_TRACE
- if (JvmtiTrace::trace_event_controller()) {
- SafeResourceMark rm;
- for (int ei = JVMTI_MIN_EVENT_TYPE_VAL; ei <= JVMTI_MAX_EVENT_TYPE_VAL; ++ei) {
- jlong bit = JvmtiEventEnabled::bit_for((jvmtiEvent)ei);
- if (changed & bit) {
- tty->print_cr("JVMTI [%s] # %s event %s",
- JvmtiTrace::safe_get_thread_name(state->get_thread()),
- (now_enabled & bit)? "Enabling" : "Disabling", JvmtiTrace::event_name((jvmtiEvent)ei));
- }
- }
- }
- #endif /*JVMTI_TRACE */
- }
- void
- JvmtiEventControllerPrivate::trace_changed(jlong now_enabled, jlong changed) {
- #ifdef JVMTI_TRACE
- if (JvmtiTrace::trace_event_controller()) {
- SafeResourceMark rm;
- for (int ei = JVMTI_MIN_EVENT_TYPE_VAL; ei <= JVMTI_MAX_EVENT_TYPE_VAL; ++ei) {
- jlong bit = JvmtiEventEnabled::bit_for((jvmtiEvent)ei);
- if (changed & bit) {
- tty->print_cr("JVMTI [-] # %s event %s",
- (now_enabled & bit)? "Enabling" : "Disabling", JvmtiTrace::event_name((jvmtiEvent)ei));
- }
- }
- }
- #endif /*JVMTI_TRACE */
- }
- jlong
- JvmtiEventControllerPrivate::recompute_env_enabled(JvmtiEnvBase* env) {
- jlong was_enabled = env->env_event_enable()->_event_enabled.get_bits();
- jlong now_enabled =
- env->env_event_enable()->_event_callback_enabled.get_bits() &
- env->env_event_enable()->_event_user_enabled.get_bits();
- switch (JvmtiEnv::get_phase()) {
- case JVMTI_PHASE_PRIMORDIAL:
- case JVMTI_PHASE_ONLOAD:
- now_enabled &= (EARLY_EVENT_BITS & ~THREAD_FILTERED_EVENT_BITS);
- break;
- case JVMTI_PHASE_START:
- now_enabled &= EARLY_EVENT_BITS;
- break;
- case JVMTI_PHASE_LIVE:
- break;
- case JVMTI_PHASE_DEAD:
- now_enabled = 0;
- break;
- default:
- assert(false, "no other phases - sanity check");
- break;
- }
- env->env_event_enable()->_event_enabled.set_bits(now_enabled);
- trace_changed(now_enabled, (now_enabled ^ was_enabled) & ~THREAD_FILTERED_EVENT_BITS);
- return now_enabled;
- }
- jlong
- JvmtiEventControllerPrivate::recompute_env_thread_enabled(JvmtiEnvThreadState* ets, JvmtiThreadState* state) {
- JvmtiEnv *env = ets->get_env();
- jlong was_enabled = ets->event_enable()->_event_enabled.get_bits();
- jlong now_enabled = THREAD_FILTERED_EVENT_BITS &
- env->env_event_enable()->_event_callback_enabled.get_bits() &
- (env->env_event_enable()->_event_user_enabled.get_bits() |
- ets->event_enable()->_event_user_enabled.get_bits());
- if (!ets->has_frame_pops()) {
- now_enabled &= ~FRAME_POP_BIT;
- }
- if (*((int *)JvmtiExport::get_field_access_count_addr()) == 0) {
- now_enabled &= ~FIELD_ACCESS_BIT;
- }
- if (*((int *)JvmtiExport::get_field_modification_count_addr()) == 0) {
- now_enabled &= ~FIELD_MODIFICATION_BIT;
- }
- switch (JvmtiEnv::get_phase()) {
- case JVMTI_PHASE_DEAD:
- now_enabled = 0;
- break;
- }
- if (now_enabled != was_enabled) {
- ets->event_enable()->_event_enabled.set_bits(now_enabled);
- jlong changed = now_enabled ^ was_enabled;
- if (changed & SINGLE_STEP_BIT) {
- ets->reset_current_location(JVMTI_EVENT_SINGLE_STEP, (now_enabled & SINGLE_STEP_BIT) != 0);
- }
- if (changed & BREAKPOINT_BIT) {
- ets->reset_current_location(JVMTI_EVENT_BREAKPOINT, (now_enabled & BREAKPOINT_BIT) != 0);
- }
- trace_changed(state, now_enabled, changed);
- }
- return now_enabled;
- }
- jlong
- JvmtiEventControllerPrivate::recompute_thread_enabled(JvmtiThreadState *state) {
- if (state == NULL) {
- return (jlong)0;
- }
- jlong was_any_env_enabled = state->thread_event_enable()->_event_enabled.get_bits();
- jlong any_env_enabled = 0;
- {
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- any_env_enabled |= recompute_env_thread_enabled(ets, state);
- }
- }
- if (any_env_enabled != was_any_env_enabled) {
- state->thread_event_enable()->_event_enabled.set_bits(any_env_enabled);
- bool should_be_interp = (any_env_enabled & INTERP_EVENT_BITS) != 0;
- bool is_now_interp = state->is_interp_only_mode();
- if (should_be_interp != is_now_interp) {
- if (should_be_interp) {
- enter_interp_only_mode(state);
- } else {
- leave_interp_only_mode(state);
- }
- }
- bool should_post_on_exceptions = (any_env_enabled & SHOULD_POST_ON_EXCEPTIONS_BITS) != 0;
- state->set_should_post_on_exceptions(should_post_on_exceptions);
- }
- return any_env_enabled;
- }
- void
- JvmtiEventControllerPrivate::recompute_enabled() {
- assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
- jlong was_any_env_thread_enabled = JvmtiEventController::_universal_global_event_enabled.get_bits();
- jlong any_env_thread_enabled = 0;
- EC_TRACE(("JVMTI [-] # recompute enabled - before %llx", was_any_env_thread_enabled));
- JvmtiEnvIterator it;
- for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
- any_env_thread_enabled |= recompute_env_enabled(env);
- }
- if ( (any_env_thread_enabled & THREAD_FILTERED_EVENT_BITS) != 0 &&
- (was_any_env_thread_enabled & THREAD_FILTERED_EVENT_BITS) == 0) {
- assert(JvmtiEnv::is_vm_live() || (JvmtiEnv::get_phase()==JVMTI_PHASE_START),
- "thread filtered events should not be enabled when VM not in start or live phase");
- {
- MutexLocker mu(Threads_lock); //hold the Threads_lock for the iteration
- for (JavaThread *tp = Threads::first(); tp != NULL; tp = tp->next()) {
- JvmtiThreadState::state_for_while_locked(tp); // create the thread state if missing
- }
- }// release Threads_lock
- }
- for (JvmtiThreadState *state = JvmtiThreadState::first(); state != NULL; state = state->next()) {
- any_env_thread_enabled |= recompute_thread_enabled(state);
- }
- jlong delta = any_env_thread_enabled ^ was_any_env_thread_enabled;
- if (delta != 0) {
- JvmtiExport::set_should_post_field_access((any_env_thread_enabled & FIELD_ACCESS_BIT) != 0);
- JvmtiExport::set_should_post_field_modification((any_env_thread_enabled & FIELD_MODIFICATION_BIT) != 0);
- JvmtiExport::set_should_post_class_load((any_env_thread_enabled & CLASS_LOAD_BIT) != 0);
- JvmtiExport::set_should_post_class_file_load_hook((any_env_thread_enabled & CLASS_FILE_LOAD_HOOK_BIT) != 0);
- JvmtiExport::set_should_post_native_method_bind((any_env_thread_enabled & NATIVE_METHOD_BIND_BIT) != 0);
- JvmtiExport::set_should_post_dynamic_code_generated((any_env_thread_enabled & DYNAMIC_CODE_GENERATED_BIT) != 0);
- JvmtiExport::set_should_post_data_dump((any_env_thread_enabled & DATA_DUMP_BIT) != 0);
- JvmtiExport::set_should_post_class_prepare((any_env_thread_enabled & CLASS_PREPARE_BIT) != 0);
- JvmtiExport::set_should_post_class_unload((any_env_thread_enabled & CLASS_UNLOAD_BIT) != 0);
- JvmtiExport::set_should_post_monitor_contended_enter((any_env_thread_enabled & MONITOR_CONTENDED_ENTER_BIT) != 0);
- JvmtiExport::set_should_post_monitor_contended_entered((any_env_thread_enabled & MONITOR_CONTENDED_ENTERED_BIT) != 0);
- JvmtiExport::set_should_post_monitor_wait((any_env_thread_enabled & MONITOR_WAIT_BIT) != 0);
- JvmtiExport::set_should_post_monitor_waited((any_env_thread_enabled & MONITOR_WAITED_BIT) != 0);
- JvmtiExport::set_should_post_garbage_collection_start((any_env_thread_enabled & GARBAGE_COLLECTION_START_BIT) != 0);
- JvmtiExport::set_should_post_garbage_collection_finish((any_env_thread_enabled & GARBAGE_COLLECTION_FINISH_BIT) != 0);
- JvmtiExport::set_should_post_object_free((any_env_thread_enabled & OBJECT_FREE_BIT) != 0);
- JvmtiExport::set_should_post_resource_exhausted((any_env_thread_enabled & RESOURCE_EXHAUSTED_BIT) != 0);
- JvmtiExport::set_should_post_compiled_method_load((any_env_thread_enabled & COMPILED_METHOD_LOAD_BIT) != 0);
- JvmtiExport::set_should_post_compiled_method_unload((any_env_thread_enabled & COMPILED_METHOD_UNLOAD_BIT) != 0);
- JvmtiExport::set_should_post_vm_object_alloc((any_env_thread_enabled & VM_OBJECT_ALLOC_BIT) != 0);
- JvmtiExport::set_should_post_thread_life((any_env_thread_enabled & NEED_THREAD_LIFE_EVENTS) != 0);
- if (delta & SINGLE_STEP_BIT) {
- switch (JvmtiEnv::get_phase()) {
- case JVMTI_PHASE_DEAD:
- break;
- case JVMTI_PHASE_LIVE: {
- VM_ChangeSingleStep op((any_env_thread_enabled & SINGLE_STEP_BIT) != 0);
- VMThread::execute(&op);
- break;
- }
- default:
- assert(false, "should never come here before live phase");
- break;
- }
- }
- JvmtiEventController::_universal_global_event_enabled.set_bits(any_env_thread_enabled);
- JvmtiExport::set_should_post_on_exceptions((any_env_thread_enabled & SHOULD_POST_ON_EXCEPTIONS_BITS) != 0);
- }
- EC_TRACE(("JVMTI [-] # recompute enabled - after %llx", any_env_thread_enabled));
- }
- void
- JvmtiEventControllerPrivate::thread_started(JavaThread *thread) {
- assert(thread->is_Java_thread(), "Must be JavaThread");
- assert(thread == Thread::current(), "must be current thread");
- assert(JvmtiEnvBase::environments_might_exist(), "to enter event controller, JVM TI environments must exist");
- EC_TRACE(("JVMTI [%s] # thread started", JvmtiTrace::safe_get_thread_name(thread)));
- if ((JvmtiEventController::_universal_global_event_enabled.get_bits() & THREAD_FILTERED_EVENT_BITS) != 0) {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiThreadState *state = JvmtiThreadState::state_for_while_locked(thread);
- if (state != NULL) { // skip threads with no JVMTI thread state
- recompute_thread_enabled(state);
- }
- }
- }
- void
- JvmtiEventControllerPrivate::thread_ended(JavaThread *thread) {
- assert(JvmtiThreadState_lock->is_locked(), "sanity check");
- EC_TRACE(("JVMTI [%s] # thread ended", JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiThreadState *state = thread->jvmti_thread_state();
- assert(state != NULL, "else why are we here?");
- delete state;
- }
- void JvmtiEventControllerPrivate::set_event_callbacks(JvmtiEnvBase *env,
- const jvmtiEventCallbacks* callbacks,
- jint size_of_callbacks) {
- assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
- EC_TRACE(("JVMTI [*] # set event callbacks"));
- env->set_event_callbacks(callbacks, size_of_callbacks);
- jlong enabled_bits = 0;
- for (int ei = JVMTI_MIN_EVENT_TYPE_VAL; ei <= JVMTI_MAX_EVENT_TYPE_VAL; ++ei) {
- jvmtiEvent evt_t = (jvmtiEvent)ei;
- if (env->has_callback(evt_t)) {
- enabled_bits |= JvmtiEventEnabled::bit_for(evt_t);
- }
- }
- env->env_event_enable()->_event_callback_enabled.set_bits(enabled_bits);
- recompute_enabled();
- }
- void
- JvmtiEventControllerPrivate::set_extension_event_callback(JvmtiEnvBase *env,
- jint extension_event_index,
- jvmtiExtensionEvent callback)
- {
- assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
- EC_TRACE(("JVMTI [*] # set extension event callback"));
- assert(extension_event_index >= (jint)EXT_MIN_EVENT_TYPE_VAL &&
- extension_event_index <= (jint)EXT_MAX_EVENT_TYPE_VAL, "sanity check");
- jvmtiEvent event_type = (jvmtiEvent)extension_event_index;
- bool enabling = (callback != NULL) && (env->is_valid());
- env->env_event_enable()->set_user_enabled(event_type, enabling);
- jvmtiExtEventCallbacks* ext_callbacks = env->ext_callbacks();
- switch (extension_event_index) {
- case EXT_EVENT_CLASS_UNLOAD :
- ext_callbacks->ClassUnload = callback;
- break;
- default:
- ShouldNotReachHere();
- }
- jlong enabled_bits = env->env_event_enable()->_event_callback_enabled.get_bits();
- jlong bit_for = JvmtiEventEnabled::bit_for(event_type);
- if (enabling) {
- enabled_bits |= bit_for;
- } else {
- enabled_bits &= ~bit_for;
- }
- env->env_event_enable()->_event_callback_enabled.set_bits(enabled_bits);
- recompute_enabled();
- }
- void
- JvmtiEventControllerPrivate::env_initialize(JvmtiEnvBase *env) {
- assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
- EC_TRACE(("JVMTI [*] # env initialize"));
- if (JvmtiEnvBase::is_vm_live()) {
- event_init();
- }
- env->initialize();
- for (JvmtiThreadState *state = JvmtiThreadState::first(); state != NULL; state = state->next()) {
- state->add_env(env);
- assert((JvmtiEnv*)(state->env_thread_state(env)->get_env()) == env, "sanity check");
- }
- JvmtiEventControllerPrivate::recompute_enabled();
- }
- void
- JvmtiEventControllerPrivate::env_dispose(JvmtiEnvBase *env) {
- assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
- EC_TRACE(("JVMTI [*] # env dispose"));
- set_event_callbacks(env, NULL, 0);
- for (jint extension_event_index = EXT_MIN_EVENT_TYPE_VAL;
- extension_event_index <= EXT_MAX_EVENT_TYPE_VAL;
- ++extension_event_index) {
- set_extension_event_callback(env, extension_event_index, NULL);
- }
- env->env_dispose();
- }
- void
- JvmtiEventControllerPrivate::set_user_enabled(JvmtiEnvBase *env, JavaThread *thread,
- jvmtiEvent event_type, bool enabled) {
- assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
- EC_TRACE(("JVMTI [%s] # user %s event %s",
- thread==NULL? "ALL": JvmtiTrace::safe_get_thread_name(thread),
- enabled? "enabled" : "disabled", JvmtiTrace::event_name(event_type)));
- if (thread == NULL) {
- env->env_event_enable()->set_user_enabled(event_type, enabled);
- } else {
- JvmtiThreadState *state = JvmtiThreadState::state_for_while_locked(thread);
- if (state != NULL) {
- state->env_thread_state(env)->event_enable()->set_user_enabled(event_type, enabled);
- }
- }
- recompute_enabled();
- }
- void
- JvmtiEventControllerPrivate::set_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
- EC_TRACE(("JVMTI [%s] # set frame pop - frame=%d",
- JvmtiTrace::safe_get_thread_name(ets->get_thread()),
- fpop.frame_number() ));
- ets->get_frame_pops()->set(fpop);
- recompute_thread_enabled(ets->get_thread()->jvmti_thread_state());
- }
- void
- JvmtiEventControllerPrivate::clear_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
- EC_TRACE(("JVMTI [%s] # clear frame pop - frame=%d",
- JvmtiTrace::safe_get_thread_name(ets->get_thread()),
- fpop.frame_number() ));
- ets->get_frame_pops()->clear(fpop);
- recompute_thread_enabled(ets->get_thread()->jvmti_thread_state());
- }
- void
- JvmtiEventControllerPrivate::clear_to_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
- int cleared_cnt = ets->get_frame_pops()->clear_to(fpop);
- EC_TRACE(("JVMTI [%s] # clear to frame pop - frame=%d, count=%d",
- JvmtiTrace::safe_get_thread_name(ets->get_thread()),
- fpop.frame_number(),
- cleared_cnt ));
- if (cleared_cnt > 0) {
- recompute_thread_enabled(ets->get_thread()->jvmti_thread_state());
- }
- }
- void
- JvmtiEventControllerPrivate::change_field_watch(jvmtiEvent event_type, bool added) {
- int *count_addr;
- switch (event_type) {
- case JVMTI_EVENT_FIELD_MODIFICATION:
- count_addr = (int *)JvmtiExport::get_field_modification_count_addr();
- break;
- case JVMTI_EVENT_FIELD_ACCESS:
- count_addr = (int *)JvmtiExport::get_field_access_count_addr();
- break;
- default:
- assert(false, "incorrect event");
- return;
- }
- EC_TRACE(("JVMTI [-] # change field watch - %s %s count=%d",
- event_type==JVMTI_EVENT_FIELD_MODIFICATION? "modification" : "access",
- added? "add" : "remove",
- if (added) {
- (*count_addr)++;
- if (*count_addr == 1) {
- recompute_enabled();
- }
- } else {
- if (*count_addr > 0) {
- (*count_addr)--;
- if (*count_addr == 0) {
- recompute_enabled();
- }
- } else {
- assert(false, "field watch out of phase");
- }
- }
- }
- void
- JvmtiEventControllerPrivate::event_init() {
- assert(JvmtiThreadState_lock->is_locked(), "sanity check");
- if (_initialized) {
- return;
- }
- EC_TRACE(("JVMTI [-] # VM live"));
- #ifdef ASSERT
- for (int ei = JVMTI_MIN_EVENT_TYPE_VAL; ei <= JVMTI_MAX_EVENT_TYPE_VAL; ++ei) {
- jlong bit = JvmtiEventEnabled::bit_for((jvmtiEvent)ei);
- assert(((THREAD_FILTERED_EVENT_BITS & bit) != 0) == JvmtiUtil::event_threaded(ei),
- "thread filtered event list does not match");
- }
- #endif
- _initialized = true;
- }
- void
- JvmtiEventControllerPrivate::vm_start() {
- JvmtiEventControllerPrivate::recompute_enabled();
- }
- void
- JvmtiEventControllerPrivate::vm_init() {
- event_init();
- JvmtiEventControllerPrivate::recompute_enabled();
- }
- void
- JvmtiEventControllerPrivate::vm_death() {
- JvmtiEventControllerPrivate::recompute_enabled();
- }
- JvmtiEventEnabled JvmtiEventController::_universal_global_event_enabled;
- bool
- JvmtiEventController::is_global_event(jvmtiEvent event_type) {
- assert(is_valid_event_type(event_type), "invalid event type");
- jlong bit_for = ((jlong)1) << (event_type - TOTAL_MIN_EVENT_TYPE_VAL);
- return((bit_for & GLOBAL_EVENT_BITS)!=0);
- }
- void
- JvmtiEventController::set_user_enabled(JvmtiEnvBase *env, JavaThread *thread, jvmtiEvent event_type, bool enabled) {
- if (Threads::number_of_threads() == 0) {
- JvmtiEventControllerPrivate::set_user_enabled(env, thread, event_type, enabled);
- } else {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::set_user_enabled(env, thread, event_type, enabled);
- }
- }
- void
- JvmtiEventController::set_event_callbacks(JvmtiEnvBase *env,
- const jvmtiEventCallbacks* callbacks,
- jint size_of_callbacks) {
- if (Threads::number_of_threads() == 0) {
- JvmtiEventControllerPrivate::set_event_callbacks(env, callbacks, size_of_callbacks);
- } else {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::set_event_callbacks(env, callbacks, size_of_callbacks);
- }
- }
- void
- JvmtiEventController::set_extension_event_callback(JvmtiEnvBase *env,
- jint extension_event_index,
- jvmtiExtensionEvent callback) {
- if (Threads::number_of_threads() == 0) {
- JvmtiEventControllerPrivate::set_extension_event_callback(env, extension_event_index, callback);
- } else {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::set_extension_event_callback(env, extension_event_index, callback);
- }
- }
- void
- JvmtiEventController::set_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::set_frame_pop(ets, fpop);
- }
- void
- JvmtiEventController::clear_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::clear_frame_pop(ets, fpop);
- }
- void
- JvmtiEventController::clear_to_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::clear_to_frame_pop(ets, fpop);
- }
- void
- JvmtiEventController::change_field_watch(jvmtiEvent event_type, bool added) {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::change_field_watch(event_type, added);
- }
- void
- JvmtiEventController::thread_started(JavaThread *thread) {
- JvmtiEventControllerPrivate::thread_started(thread);
- }
- void
- JvmtiEventController::thread_ended(JavaThread *thread) {
- JvmtiEventControllerPrivate::thread_ended(thread);
- }
- void
- JvmtiEventController::env_initialize(JvmtiEnvBase *env) {
- if (Threads::number_of_threads() == 0) {
- JvmtiEventControllerPrivate::env_initialize(env);
- } else {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::env_initialize(env);
- }
- }
- void
- JvmtiEventController::env_dispose(JvmtiEnvBase *env) {
- if (Threads::number_of_threads() == 0) {
- JvmtiEventControllerPrivate::env_dispose(env);
- } else {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::env_dispose(env);
- }
- }
- void
- JvmtiEventController::vm_start() {
- if (JvmtiEnvBase::environments_might_exist()) {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::vm_start();
- }
- }
- void
- JvmtiEventController::vm_init() {
- if (JvmtiEnvBase::environments_might_exist()) {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::vm_init();
- }
- }
- void
- JvmtiEventController::vm_death() {
- if (JvmtiEnvBase::environments_might_exist()) {
- MutexLocker mu(JvmtiThreadState_lock);
- JvmtiEventControllerPrivate::vm_death();
- }
- }
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiEventController.hpp
- #ifndef SHARE_VM_PRIMS_JVMTIEVENTCONTROLLER_HPP
- #define SHARE_VM_PRIMS_JVMTIEVENTCONTROLLER_HPP
- #include "jvmtifiles/jvmti.h"
- #include "memory/allocation.hpp"
- #include "memory/allocation.inline.hpp"
- #include "utilities/globalDefinitions.hpp"
- class JvmtiEventControllerPrivate;
- class JvmtiEventController;
- class JvmtiEnvThreadState;
- class JvmtiFramePop;
- class JvmtiEnvBase;
- typedef enum {
- EXT_EVENT_CLASS_UNLOAD = JVMTI_MIN_EVENT_TYPE_VAL-1,
- EXT_MIN_EVENT_TYPE_VAL = EXT_EVENT_CLASS_UNLOAD,
- EXT_MAX_EVENT_TYPE_VAL = EXT_EVENT_CLASS_UNLOAD
- } jvmtiExtEvent;
- typedef struct {
- jvmtiExtensionEvent ClassUnload;
- } jvmtiExtEventCallbacks;
- const int TOTAL_MIN_EVENT_TYPE_VAL = EXT_MIN_EVENT_TYPE_VAL;
- const int TOTAL_MAX_EVENT_TYPE_VAL = JVMTI_MAX_EVENT_TYPE_VAL;
- class JvmtiEventEnabled VALUE_OBJ_CLASS_SPEC {
- private:
- friend class JvmtiEventControllerPrivate;
- jlong _enabled_bits;
- #ifndef PRODUCT
- enum {
- JEE_INIT_GUARD = 0xEAD0
- } _init_guard;
- #endif
- static jlong bit_for(jvmtiEvent event_type);
- jlong get_bits();
- void set_bits(jlong bits);
- public:
- JvmtiEventEnabled();
- void clear();
- bool is_enabled(jvmtiEvent event_type);
- void set_enabled(jvmtiEvent event_type, bool enabled);
- };
- class JvmtiEnvThreadEventEnable VALUE_OBJ_CLASS_SPEC {
- private:
- friend class JvmtiEventControllerPrivate;
- JvmtiEventEnabled _event_user_enabled;
- JvmtiEventEnabled _event_enabled;
- public:
- JvmtiEnvThreadEventEnable();
- ~JvmtiEnvThreadEventEnable();
- bool is_enabled(jvmtiEvent event_type);
- void set_user_enabled(jvmtiEvent event_type, bool enabled);
- };
- class JvmtiThreadEventEnable VALUE_OBJ_CLASS_SPEC {
- private:
- friend class JvmtiEventControllerPrivate;
- JvmtiEventEnabled _event_enabled;
- public:
- JvmtiThreadEventEnable();
- ~JvmtiThreadEventEnable();
- bool is_enabled(jvmtiEvent event_type);
- };
- class JvmtiEnvEventEnable VALUE_OBJ_CLASS_SPEC {
- private:
- friend class JvmtiEventControllerPrivate;
- JvmtiEventEnabled _event_user_enabled;
- JvmtiEventEnabled _event_callback_enabled;
- JvmtiEventEnabled _event_enabled;
- public:
- JvmtiEnvEventEnable();
- ~JvmtiEnvEventEnable();
- bool is_enabled(jvmtiEvent event_type);
- void set_user_enabled(jvmtiEvent event_type, bool enabled);
- };
- class JvmtiEventController : AllStatic {
- private:
- friend class JvmtiEventControllerPrivate;
- static JvmtiEventEnabled _universal_global_event_enabled;
- public:
- static bool is_enabled(jvmtiEvent event_type);
- static bool is_global_event(jvmtiEvent event_type);
- static bool is_valid_event_type(jvmtiEvent event_type) {
- return ((int)event_type >= TOTAL_MIN_EVENT_TYPE_VAL)
- && ((int)event_type <= TOTAL_MAX_EVENT_TYPE_VAL);
- }
- static void set_user_enabled(JvmtiEnvBase *env, JavaThread *thread,
- jvmtiEvent event_type, bool enabled);
- static void set_event_callbacks(JvmtiEnvBase *env,
- const jvmtiEventCallbacks* callbacks,
- jint size_of_callbacks);
- static void set_extension_event_callback(JvmtiEnvBase* env,
- jint extension_event_index,
- jvmtiExtensionEvent callback);
- static void set_frame_pop(JvmtiEnvThreadState *env_thread, JvmtiFramePop fpop);
- static void clear_frame_pop(JvmtiEnvThreadState *env_thread, JvmtiFramePop fpop);
- static void clear_to_frame_pop(JvmtiEnvThreadState *env_thread, JvmtiFramePop fpop);
- static void change_field_watch(jvmtiEvent event_type, bool added);
- static void thread_started(JavaThread *thread);
- static void thread_ended(JavaThread *thread);
- static void env_initialize(JvmtiEnvBase *env);
- static void env_dispose(JvmtiEnvBase *env);
- static void vm_start();
- static void vm_init();
- static void vm_death();
- };
- #endif // SHARE_VM_PRIMS_JVMTIEVENTCONTROLLER_HPP
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiEventController.inline.hpp
- #ifndef SHARE_VM_PRIMS_JVMTIEVENTCONTROLLER_INLINE_HPP
- #define SHARE_VM_PRIMS_JVMTIEVENTCONTROLLER_INLINE_HPP
- #include "prims/jvmtiEventController.hpp"
- #include "prims/jvmtiImpl.hpp"
- #include "prims/jvmtiUtil.hpp"
- inline jlong JvmtiEventEnabled::bit_for(jvmtiEvent event_type) {
- assert(JvmtiEventController::is_valid_event_type(event_type), "invalid event type");
- return ((jlong)1) << (event_type - TOTAL_MIN_EVENT_TYPE_VAL);
- }
- inline jlong JvmtiEventEnabled::get_bits() {
- assert(_init_guard == JEE_INIT_GUARD, "enable bits uninitialized or corrupted");
- return _enabled_bits;
- }
- inline void JvmtiEventEnabled::set_bits(jlong bits) {
- assert(_init_guard == JEE_INIT_GUARD, "enable bits uninitialized or corrupted on set");
- _enabled_bits = bits;
- }
- inline bool JvmtiEventEnabled::is_enabled(jvmtiEvent event_type) {
- return (bit_for(event_type) & get_bits()) != 0;
- }
- inline bool JvmtiEnvThreadEventEnable::is_enabled(jvmtiEvent event_type) {
- assert(JvmtiUtil::event_threaded(event_type), "Only thread filtered events should be tested here");
- return _event_enabled.is_enabled(event_type);
- }
- inline void JvmtiEnvThreadEventEnable::set_user_enabled(jvmtiEvent event_type, bool enabled) {
- _event_user_enabled.set_enabled(event_type, enabled);
- }
- inline bool JvmtiThreadEventEnable::is_enabled(jvmtiEvent event_type) {
- assert(JvmtiUtil::event_threaded(event_type), "Only thread filtered events should be tested here");
- return _event_enabled.is_enabled(event_type);
- }
- inline bool JvmtiEnvEventEnable::is_enabled(jvmtiEvent event_type) {
- assert(!JvmtiUtil::event_threaded(event_type), "Only non thread filtered events should be tested here");
- return _event_enabled.is_enabled(event_type);
- }
- inline void JvmtiEnvEventEnable::set_user_enabled(jvmtiEvent event_type, bool enabled) {
- _event_user_enabled.set_enabled(event_type, enabled);
- }
- inline bool JvmtiEventController::is_enabled(jvmtiEvent event_type) {
- return _universal_global_event_enabled.is_enabled(event_type);
- }
- #endif // SHARE_VM_PRIMS_JVMTIEVENTCONTROLLER_INLINE_HPP
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiExport.cpp
- #include "precompiled.hpp"
- #include "classfile/systemDictionary.hpp"
- #include "code/nmethod.hpp"
- #include "code/pcDesc.hpp"
- #include "code/scopeDesc.hpp"
- #include "interpreter/interpreter.hpp"
- #include "jvmtifiles/jvmtiEnv.hpp"
- #include "memory/resourceArea.hpp"
- #include "oops/objArrayKlass.hpp"
- #include "oops/objArrayOop.hpp"
- #include "prims/jvmtiCodeBlobEvents.hpp"
- #include "prims/jvmtiEventController.hpp"
- #include "prims/jvmtiEventController.inline.hpp"
- #include "prims/jvmtiExport.hpp"
- #include "prims/jvmtiImpl.hpp"
- #include "prims/jvmtiManageCapabilities.hpp"
- #include "prims/jvmtiRawMonitor.hpp"
- #include "prims/jvmtiTagMap.hpp"
- #include "prims/jvmtiThreadState.inline.hpp"
- #include "prims/jvmtiRedefineClasses.hpp"
- #include "runtime/arguments.hpp"
- #include "runtime/handles.hpp"
- #include "runtime/interfaceSupport.hpp"
- #include "runtime/objectMonitor.hpp"
- #include "runtime/objectMonitor.inline.hpp"
- #include "runtime/thread.inline.hpp"
- #include "runtime/vframe.hpp"
- #include "services/attachListener.hpp"
- #include "services/serviceUtil.hpp"
- #include "utilities/macros.hpp"
- #if INCLUDE_ALL_GCS
- #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
- #endif // INCLUDE_ALL_GCS
- PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
- #ifdef JVMTI_TRACE
- #define EVT_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_SENT) != 0) { SafeResourceMark rm; tty->print_cr out; }
- #define EVT_TRIG_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_TRIGGER) != 0) { SafeResourceMark rm; tty->print_cr out; }
- #else
- #define EVT_TRIG_TRACE(evt,out)
- #define EVT_TRACE(evt,out)
- #endif
- class JvmtiJavaThreadEventTransition : StackObj {
- private:
- ResourceMark _rm;
- ThreadToNativeFromVM _transition;
- HandleMark _hm;
- public:
- JvmtiJavaThreadEventTransition(JavaThread *thread) :
- _rm(),
- _transition(thread),
- _hm(thread) {};
- };
- class JvmtiThreadEventTransition : StackObj {
- private:
- ResourceMark _rm;
- HandleMark _hm;
- JavaThreadState _saved_state;
- JavaThread *_jthread;
- public:
- JvmtiThreadEventTransition(Thread *thread) : _rm(), _hm() {
- if (thread->is_Java_thread()) {
- _jthread = (JavaThread *)thread;
- _saved_state = _jthread->thread_state();
- if (_saved_state == _thread_in_Java) {
- ThreadStateTransition::transition_from_java(_jthread, _thread_in_native);
- } else {
- ThreadStateTransition::transition(_jthread, _saved_state, _thread_in_native);
- }
- } else {
- _jthread = NULL;
- }
- }
- ~JvmtiThreadEventTransition() {
- if (_jthread != NULL)
- ThreadStateTransition::transition_from_native(_jthread, _saved_state);
- }
- };
- class JvmtiEventMark : public StackObj {
- private:
- JavaThread *_thread;
- JNIEnv* _jni_env;
- bool _exception_detected;
- bool _exception_caught;
- #if 0
- JNIHandleBlock* _hblock;
- #endif
- public:
- JvmtiEventMark(JavaThread *thread) : _thread(thread),
- _jni_env(thread->jni_environment()) {
- #if 0
- _hblock = thread->active_handles();
- _hblock->clear_thoroughly(); // so we can be safe
- #else
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state != NULL) {
- _exception_detected = state->is_exception_detected();
- _exception_caught = state->is_exception_caught();
- } else {
- _exception_detected = false;
- _exception_caught = false;
- }
- JNIHandleBlock* old_handles = thread->active_handles();
- JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);
- assert(new_handles != NULL, "should not be NULL");
- new_handles->set_pop_frame_link(old_handles);
- thread->set_active_handles(new_handles);
- #endif
- assert(thread == JavaThread::current(), "thread must be current!");
- thread->frame_anchor()->make_walkable(thread);
- };
- ~JvmtiEventMark() {
- #if 0
- _hblock->clear(); // for consistency with future correct behavior
- #else
- JNIHandleBlock* old_handles = _thread->active_handles();
- JNIHandleBlock* new_handles = old_handles->pop_frame_link();
- assert(new_handles != NULL, "should not be NULL");
- _thread->set_active_handles(new_handles);
- old_handles->set_pop_frame_link(NULL);
- JNIHandleBlock::release_block(old_handles, _thread); // may block
- #endif
- JvmtiThreadState* state = _thread->jvmti_thread_state();
- if (state != NULL) {
- if (_exception_detected) {
- state->set_exception_detected();
- }
- if (_exception_caught) {
- state->set_exception_caught();
- }
- }
- }
- #if 0
- jobject to_jobject(oop obj) { return obj == NULL? NULL : _hblock->allocate_handle_fast(obj); }
- #else
- jobject to_jobject(oop obj) { return JNIHandles::make_local(_thread,obj); }
- #endif
- jclass to_jclass(Klass* klass) { return (klass == NULL ? NULL : (jclass)to_jobject(klass->java_mirror())); }
- jmethodID to_jmethodID(methodHandle method) { return method->jmethod_id(); }
- JNIEnv* jni_env() { return _jni_env; }
- };
- class JvmtiThreadEventMark : public JvmtiEventMark {
- private:
- jthread _jt;
- public:
- JvmtiThreadEventMark(JavaThread *thread) :
- JvmtiEventMark(thread) {
- _jt = (jthread)(to_jobject(thread->threadObj()));
- };
- jthread jni_thread() { return _jt; }
- };
- class JvmtiClassEventMark : public JvmtiThreadEventMark {
- private:
- jclass _jc;
- public:
- JvmtiClassEventMark(JavaThread *thread, Klass* klass) :
- JvmtiThreadEventMark(thread) {
- _jc = to_jclass(klass);
- };
- jclass jni_class() { return _jc; }
- };
- class JvmtiMethodEventMark : public JvmtiThreadEventMark {
- private:
- jmethodID _mid;
- public:
- JvmtiMethodEventMark(JavaThread *thread, methodHandle method) :
- JvmtiThreadEventMark(thread),
- _mid(to_jmethodID(method)) {};
- jmethodID jni_methodID() { return _mid; }
- };
- class JvmtiLocationEventMark : public JvmtiMethodEventMark {
- private:
- jlocation _loc;
- public:
- JvmtiLocationEventMark(JavaThread *thread, methodHandle method, address location) :
- JvmtiMethodEventMark(thread, method),
- _loc(location - method->code_base()) {};
- jlocation location() { return _loc; }
- };
- class JvmtiExceptionEventMark : public JvmtiLocationEventMark {
- private:
- jobject _exc;
- public:
- JvmtiExceptionEventMark(JavaThread *thread, methodHandle method, address location, Handle exception) :
- JvmtiLocationEventMark(thread, method, location),
- _exc(to_jobject(exception())) {};
- jobject exception() { return _exc; }
- };
- class JvmtiClassFileLoadEventMark : public JvmtiThreadEventMark {
- private:
- const char *_class_name;
- jobject _jloader;
- jobject _protection_domain;
- jclass _class_being_redefined;
- public:
- JvmtiClassFileLoadEventMark(JavaThread *thread, Symbol* name,
- Handle class_loader, Handle prot_domain, KlassHandle *class_being_redefined) : JvmtiThreadEventMark(thread) {
- _class_name = name != NULL? name->as_utf8() : NULL;
- _jloader = (jobject)to_jobject(class_loader());
- _protection_domain = (jobject)to_jobject(prot_domain());
- if (class_being_redefined == NULL) {
- _class_being_redefined = NULL;
- } else {
- _class_being_redefined = (jclass)to_jclass((*class_being_redefined)());
- }
- };
- const char *class_name() {
- return _class_name;
- }
- jobject jloader() {
- return _jloader;
- }
- jobject protection_domain() {
- return _protection_domain;
- }
- jclass class_being_redefined() {
- return _class_being_redefined;
- }
- };
- int JvmtiExport::_field_access_count = 0;
- int JvmtiExport::_field_modification_count = 0;
- bool JvmtiExport::_can_access_local_variables = false;
- bool JvmtiExport::_can_hotswap_or_post_breakpoint = false;
- bool JvmtiExport::_can_modify_any_class = false;
- bool JvmtiExport::_can_walk_any_space = false;
- bool JvmtiExport::_has_redefined_a_class = false;
- bool JvmtiExport::_all_dependencies_are_recorded = false;
- address JvmtiExport::get_field_access_count_addr() {
- return (address)(&_field_access_count);
- }
- address JvmtiExport::get_field_modification_count_addr() {
- return (address)(&_field_modification_count);
- }
- jint
- JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {
- int major, minor, micro;
- decode_version_values(version, &major, &minor, µ);
- switch (major) {
- case 1:
- switch (minor) {
- case 0: // version 1.0.<micro> is recognized
- case 1: // version 1.1.<micro> is recognized
- case 2: // version 1.2.<micro> is recognized
- break;
- default:
- return JNI_EVERSION; // unsupported minor version number
- }
- break;
- default:
- return JNI_EVERSION; // unsupported major version number
- }
- if (JvmtiEnv::get_phase() == JVMTI_PHASE_LIVE) {
- JavaThread* current_thread = (JavaThread*) ThreadLocalStorage::thread();
- ThreadInVMfromNative __tiv(current_thread);
- VM_ENTRY_BASE(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread)
- debug_only(VMNativeEntryWrapper __vew;)
- JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version);
- return JNI_OK;
- } else if (JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) {
- JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version);
- return JNI_OK;
- } else {
- return JNI_EDETACHED;
- }
- }
- void
- JvmtiExport::decode_version_values(jint version, int * major, int * minor,
- int * micro) {
- }
- void JvmtiExport::enter_primordial_phase() {
- JvmtiEnvBase::set_phase(JVMTI_PHASE_PRIMORDIAL);
- }
- void JvmtiExport::enter_start_phase() {
- JvmtiManageCapabilities::recompute_always_capabilities();
- JvmtiEnvBase::set_phase(JVMTI_PHASE_START);
- }
- void JvmtiExport::enter_onload_phase() {
- JvmtiEnvBase::set_phase(JVMTI_PHASE_ONLOAD);
- }
- void JvmtiExport::enter_live_phase() {
- JvmtiEnvBase::set_phase(JVMTI_PHASE_LIVE);
- }
- void JvmtiExport::post_vm_start() {
- EVT_TRIG_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Trg VM start event triggered" ));
- JvmtiEventController::vm_start();
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_VM_START)) {
- EVT_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Evt VM start event sent" ));
- JavaThread *thread = JavaThread::current();
- JvmtiThreadEventMark jem(thread);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventVMStart callback = env->callbacks()->VMStart;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env());
- }
- }
- }
- }
- void JvmtiExport::post_vm_initialized() {
- EVT_TRIG_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Trg VM init event triggered" ));
- JvmtiEventController::vm_init();
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_VM_INIT)) {
- EVT_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Evt VM init event sent" ));
- JavaThread *thread = JavaThread::current();
- JvmtiThreadEventMark jem(thread);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventVMInit callback = env->callbacks()->VMInit;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
- }
- }
- }
- }
- void JvmtiExport::post_vm_death() {
- EVT_TRIG_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Trg VM death event triggered" ));
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_VM_DEATH)) {
- EVT_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Evt VM death event sent" ));
- JavaThread *thread = JavaThread::current();
- JvmtiEventMark jem(thread);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventVMDeath callback = env->callbacks()->VMDeath;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env());
- }
- }
- }
- JvmtiEnvBase::set_phase(JVMTI_PHASE_DEAD);
- JvmtiEventController::vm_death();
- }
- char**
- JvmtiExport::get_all_native_method_prefixes(int* count_ptr) {
- if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) {
- return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
- } else {
- MutexLocker mu(JvmtiThreadState_lock);
- return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
- }
- }
- class JvmtiClassFileLoadHookPoster : public StackObj {
- private:
- Symbol* _h_name;
- Handle _class_loader;
- Handle _h_protection_domain;
- unsigned char ** _data_ptr;
- unsigned char ** _end_ptr;
- JavaThread * _thread;
- jint _curr_len;
- unsigned char * _curr_data;
- JvmtiEnv * _curr_env;
- JvmtiCachedClassFileData ** _cached_class_file_ptr;
- JvmtiThreadState * _state;
- KlassHandle * _h_class_being_redefined;
- JvmtiClassLoadKind _load_kind;
- public:
- inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader,
- Handle h_protection_domain,
- unsigned char **data_ptr, unsigned char **end_ptr,
- JvmtiCachedClassFileData **cache_ptr) {
- _h_name = h_name;
- _class_loader = class_loader;
- _h_protection_domain = h_protection_domain;
- _data_ptr = data_ptr;
- _end_ptr = end_ptr;
- _thread = JavaThread::current();
- _curr_len = *end_ptr - *data_ptr;
- _curr_data = *data_ptr;
- _curr_env = NULL;
- _cached_class_file_ptr = cache_ptr;
- _state = _thread->jvmti_thread_state();
- if (_state != NULL) {
- _h_class_being_redefined = _state->get_class_being_redefined();
- _load_kind = _state->get_class_load_kind();
- _state->clear_class_being_redefined();
- } else {
- _h_class_being_redefined = (KlassHandle *) NULL;
- _load_kind = jvmti_class_load_kind_load;
- }
- }
- void post() {
- post_all_envs();
- copy_modified_data();
- }
- private:
- void post_all_envs() {
- if (_load_kind != jvmti_class_load_kind_retransform) {
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
- post_to_env(env, false);
- }
- }
- }
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
- post_to_env(env, true);
- }
- }
- }
- void post_to_env(JvmtiEnv* env, bool caching_needed) {
- unsigned char *new_data = NULL;
- jint new_len = 0;
- JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader,
- _h_protection_domain,
- _h_class_being_redefined);
- JvmtiJavaThreadEventTransition jet(_thread);
- JNIEnv* jni_env = (JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL)?
- NULL : jem.jni_env();
- jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jni_env,
- jem.class_being_redefined(),
- jem.jloader(), jem.class_name(),
- jem.protection_domain(),
- _curr_len, _curr_data,
- &new_len, &new_data);
- }
- if (new_data != NULL) {
- if (caching_needed && *_cached_class_file_ptr == NULL) {
- JvmtiCachedClassFileData *p;
- p = (JvmtiCachedClassFileData *)os::malloc(
- offset_of(JvmtiCachedClassFileData, data) + _curr_len, mtInternal);
- if (p == NULL) {
- vm_exit_out_of_memory(offset_of(JvmtiCachedClassFileData, data) + _curr_len,
- OOM_MALLOC_ERROR,
- "unable to allocate cached copy of original class bytes");
- }
- p->length = _curr_len;
- memcpy(p->data, _curr_data, _curr_len);
- }
- if (_curr_data != *_data_ptr) {
- _curr_env->Deallocate(_curr_data);
- }
- _curr_data = new_data;
- _curr_len = new_len;
- _curr_env = env;
- }
- }
- void copy_modified_data() {
- if (_curr_data != *_data_ptr) {
- memcpy(*_data_ptr, _curr_data, _curr_len);
- _curr_env->Deallocate(_curr_data);
- }
- }
- };
- bool JvmtiExport::_should_post_class_file_load_hook = false;
- void JvmtiExport::post_class_file_load_hook(Symbol* h_name,
- Handle class_loader,
- Handle h_protection_domain,
- unsigned char **data_ptr,
- unsigned char **end_ptr,
- JvmtiCachedClassFileData **cache_ptr) {
- JvmtiClassFileLoadHookPoster poster(h_name, class_loader,
- h_protection_domain,
- data_ptr, end_ptr,
- cache_ptr);
- poster.post();
- }
- void JvmtiExport::report_unsupported(bool on) {
- if (on) {
- vm_exit_during_initialization("Java Kernel does not support JVMTI.");
- }
- }
- static inline Klass* oop_to_klass(oop obj) {
- Klass* k = obj->klass();
- if (k == SystemDictionary::Class_klass()) {
- if (!java_lang_Class::is_primitive(obj)) {
- k = java_lang_Class::as_Klass(obj);
- assert(k != NULL, "class for non-primitive mirror must exist");
- }
- }
- return k;
- }
- class JvmtiVMObjectAllocEventMark : public JvmtiClassEventMark {
- private:
- jobject _jobj;
- jlong _size;
- public:
- JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klass(obj)) {
- _jobj = (jobject)to_jobject(obj);
- _size = obj->size() * wordSize;
- };
- jobject jni_jobject() { return _jobj; }
- jlong size() { return _size; }
- };
- class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark {
- private:
- jint _code_size;
- const void *_code_data;
- jint _map_length;
- jvmtiAddrLocationMap *_map;
- const void *_compile_info;
- public:
- JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm, void* compile_info_ptr = NULL)
- : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {
- _code_data = nm->insts_begin();
- _code_size = nm->insts_size();
- _compile_info = compile_info_ptr; // Set void pointer of compiledMethodLoad Event. Default value is NULL.
- JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
- }
- ~JvmtiCompiledMethodLoadEventMark() {
- FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map, mtInternal);
- }
- jint code_size() { return _code_size; }
- const void *code_data() { return _code_data; }
- jint map_length() { return _map_length; }
- const jvmtiAddrLocationMap* map() { return _map; }
- const void *compile_info() { return _compile_info; }
- };
- class JvmtiMonitorEventMark : public JvmtiThreadEventMark {
- private:
- jobject _jobj;
- public:
- JvmtiMonitorEventMark(JavaThread *thread, oop object)
- : JvmtiThreadEventMark(thread){
- _jobj = to_jobject(object);
- }
- jobject jni_object() { return _jobj; }
- };
- void JvmtiExport::post_compiled_method_unload(
- jmethodID method, const void *code_begin) {
- JavaThread* thread = JavaThread::current();
- EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
- ("JVMTI [%s] method compile unload event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) {
- EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
- ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT,
- JvmtiTrace::safe_get_thread_name(thread), method));
- ResourceMark rm(thread);
- JvmtiEventMark jem(thread);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), method, code_begin);
- }
- }
- }
- }
- void JvmtiExport::post_raw_breakpoint(JavaThread *thread, Method* method, address location) {
- HandleMark hm(thread);
- methodHandle mh(thread, method);
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Trg Breakpoint triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_BREAKPOINT);
- if (!ets->breakpoint_posted() && ets->is_enabled(JVMTI_EVENT_BREAKPOINT)) {
- ThreadState old_os_state = thread->osthread()->get_state();
- thread->osthread()->set_state(BREAKPOINTED);
- EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Evt Breakpoint sent %s.%s @ %d",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
- location - mh()->code_base() ));
- JvmtiEnv *env = ets->get_env();
- JvmtiLocationEventMark jem(thread, mh, location);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventBreakpoint callback = env->callbacks()->Breakpoint;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
- jem.jni_methodID(), jem.location());
- }
- ets->set_breakpoint_posted();
- thread->osthread()->set_state(old_os_state);
- }
- }
- }
- bool JvmtiExport::_can_get_source_debug_extension = false;
- bool JvmtiExport::_can_maintain_original_method_order = false;
- bool JvmtiExport::_can_post_interpreter_events = false;
- bool JvmtiExport::_can_post_on_exceptions = false;
- bool JvmtiExport::_can_post_breakpoint = false;
- bool JvmtiExport::_can_post_field_access = false;
- bool JvmtiExport::_can_post_field_modification = false;
- bool JvmtiExport::_can_post_method_entry = false;
- bool JvmtiExport::_can_post_method_exit = false;
- bool JvmtiExport::_can_pop_frame = false;
- bool JvmtiExport::_can_force_early_return = false;
- bool JvmtiExport::_should_post_single_step = false;
- bool JvmtiExport::_should_post_field_access = false;
- bool JvmtiExport::_should_post_field_modification = false;
- bool JvmtiExport::_should_post_class_load = false;
- bool JvmtiExport::_should_post_class_prepare = false;
- bool JvmtiExport::_should_post_class_unload = false;
- bool JvmtiExport::_should_post_thread_life = false;
- bool JvmtiExport::_should_clean_up_heap_objects = false;
- bool JvmtiExport::_should_post_native_method_bind = false;
- bool JvmtiExport::_should_post_dynamic_code_generated = false;
- bool JvmtiExport::_should_post_data_dump = false;
- bool JvmtiExport::_should_post_compiled_method_load = false;
- bool JvmtiExport::_should_post_compiled_method_unload = false;
- bool JvmtiExport::_should_post_monitor_contended_enter = false;
- bool JvmtiExport::_should_post_monitor_contended_entered = false;
- bool JvmtiExport::_should_post_monitor_wait = false;
- bool JvmtiExport::_should_post_monitor_waited = false;
- bool JvmtiExport::_should_post_garbage_collection_start = false;
- bool JvmtiExport::_should_post_garbage_collection_finish = false;
- bool JvmtiExport::_should_post_object_free = false;
- bool JvmtiExport::_should_post_resource_exhausted = false;
- bool JvmtiExport::_should_post_vm_object_alloc = false;
- bool JvmtiExport::_should_post_on_exceptions = false;
- void JvmtiExport::at_single_stepping_point(JavaThread *thread, Method* method, address location) {
- assert(JvmtiExport::should_post_single_step(), "must be single stepping");
- HandleMark hm(thread);
- methodHandle mh(thread, method);
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- EVT_TRIG_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Trg Single Step triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- if (!state->hide_single_stepping()) {
- if (state->is_pending_step_for_popframe()) {
- state->process_pending_step_for_popframe();
- }
- if (state->is_pending_step_for_earlyret()) {
- state->process_pending_step_for_earlyret();
- }
- JvmtiExport::post_single_step(thread, mh(), location);
- }
- }
- void JvmtiExport::expose_single_stepping(JavaThread *thread) {
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state != NULL) {
- state->clear_hide_single_stepping();
- }
- }
- bool JvmtiExport::hide_single_stepping(JavaThread *thread) {
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state != NULL && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
- state->set_hide_single_stepping();
- return true;
- } else {
- return false;
- }
- }
- void JvmtiExport::post_class_load(JavaThread *thread, Klass* klass) {
- HandleMark hm(thread);
- KlassHandle kh(thread, klass);
- EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_LOAD, ("JVMTI [%s] Trg Class Load triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiThreadState* state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_CLASS_LOAD)) {
- EVT_TRACE(JVMTI_EVENT_CLASS_LOAD, ("JVMTI [%s] Evt Class Load sent %s",
- JvmtiTrace::safe_get_thread_name(thread),
- kh()==NULL? "NULL" : kh()->external_name() ));
- JvmtiEnv *env = ets->get_env();
- JvmtiClassEventMark jem(thread, kh());
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventClassLoad callback = env->callbacks()->ClassLoad;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class());
- }
- }
- }
- }
- void JvmtiExport::post_class_prepare(JavaThread *thread, Klass* klass) {
- HandleMark hm(thread);
- KlassHandle kh(thread, klass);
- EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("JVMTI [%s] Trg Class Prepare triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiThreadState* state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_CLASS_PREPARE)) {
- EVT_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("JVMTI [%s] Evt Class Prepare sent %s",
- JvmtiTrace::safe_get_thread_name(thread),
- kh()==NULL? "NULL" : kh()->external_name() ));
- JvmtiEnv *env = ets->get_env();
- JvmtiClassEventMark jem(thread, kh());
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventClassPrepare callback = env->callbacks()->ClassPrepare;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class());
- }
- }
- }
- }
- void JvmtiExport::post_class_unload(Klass* klass) {
- Thread *thread = Thread::current();
- HandleMark hm(thread);
- KlassHandle kh(thread, klass);
- EVT_TRIG_TRACE(EXT_EVENT_CLASS_UNLOAD, ("JVMTI [?] Trg Class Unload triggered" ));
- if (JvmtiEventController::is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) {
- assert(thread->is_VM_thread(), "wrong thread");
- JavaThread *real_thread =
- (JavaThread *)((VMThread *)thread)->vm_operation()->calling_thread();
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) {
- EVT_TRACE(EXT_EVENT_CLASS_UNLOAD, ("JVMTI [?] Evt Class Unload sent %s",
- kh()==NULL? "NULL" : kh()->external_name() ));
- JNIEnv* jni_env = real_thread->jni_environment();
- jthread jt = (jthread)JNIHandles::make_local(real_thread, real_thread->threadObj());
- jclass jk = (jclass)JNIHandles::make_local(real_thread, kh()->java_mirror());
- JavaThreadState prev_state = real_thread->thread_state();
- assert(((Thread *)real_thread)->is_ConcurrentGC_thread() ||
- (real_thread->is_Java_thread() && prev_state == _thread_blocked),
- "should be ConcurrentGCThread or JavaThread at safepoint");
- real_thread->set_thread_state(_thread_in_native);
- jvmtiExtensionEvent callback = env->ext_callbacks()->ClassUnload;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jni_env, jt, jk);
- }
- assert(real_thread->thread_state() == _thread_in_native,
- "JavaThread should be in native");
- real_thread->set_thread_state(prev_state);
- JNIHandles::destroy_local(jk);
- JNIHandles::destroy_local(jt);
- }
- }
- }
- }
- void JvmtiExport::post_thread_start(JavaThread *thread) {
- assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
- EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_START, ("JVMTI [%s] Trg Thread Start event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEventController::thread_started(thread);
- if (JvmtiEventController::is_enabled(JVMTI_EVENT_THREAD_START) &&
- !thread->is_hidden_from_external_view()) {
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_THREAD_START)) {
- EVT_TRACE(JVMTI_EVENT_THREAD_START, ("JVMTI [%s] Evt Thread Start event sent",
- JvmtiTrace::safe_get_thread_name(thread) ));
- JvmtiThreadEventMark jem(thread);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventThreadStart callback = env->callbacks()->ThreadStart;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
- }
- }
- }
- }
- }
- void JvmtiExport::post_thread_end(JavaThread *thread) {
- EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_END, ("JVMTI [%s] Trg Thread End event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- if (state->is_enabled(JVMTI_EVENT_THREAD_END) &&
- !thread->is_hidden_from_external_view()) {
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_THREAD_END)) {
- EVT_TRACE(JVMTI_EVENT_THREAD_END, ("JVMTI [%s] Evt Thread End event sent",
- JvmtiTrace::safe_get_thread_name(thread) ));
- JvmtiEnv *env = ets->get_env();
- JvmtiThreadEventMark jem(thread);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventThreadEnd callback = env->callbacks()->ThreadEnd;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
- }
- }
- }
- }
- }
- void JvmtiExport::post_object_free(JvmtiEnv* env, jlong tag) {
- assert(SafepointSynchronize::is_at_safepoint(), "must be executed at safepoint");
- assert(env->is_enabled(JVMTI_EVENT_OBJECT_FREE), "checking");
- EVT_TRIG_TRACE(JVMTI_EVENT_OBJECT_FREE, ("JVMTI [?] Trg Object Free triggered" ));
- EVT_TRACE(JVMTI_EVENT_OBJECT_FREE, ("JVMTI [?] Evt Object Free sent"));
- jvmtiEventObjectFree callback = env->callbacks()->ObjectFree;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), tag);
- }
- }
- void JvmtiExport::post_resource_exhausted(jint resource_exhausted_flags, const char* description) {
- EVT_TRIG_TRACE(JVMTI_EVENT_RESOURCE_EXHAUSTED, ("JVMTI Trg resource exhausted event triggered" ));
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_RESOURCE_EXHAUSTED)) {
- EVT_TRACE(JVMTI_EVENT_RESOURCE_EXHAUSTED, ("JVMTI Evt resource exhausted event sent" ));
- JavaThread *thread = JavaThread::current();
- JvmtiThreadEventMark jem(thread);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventResourceExhausted callback = env->callbacks()->ResourceExhausted;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(),
- resource_exhausted_flags, NULL, description);
- }
- }
- }
- }
- void JvmtiExport::post_method_entry(JavaThread *thread, Method* method, frame current_frame) {
- HandleMark hm(thread);
- methodHandle mh(thread, method);
- EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_ENTRY, ("JVMTI [%s] Trg Method Entry triggered %s.%s",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));
- JvmtiThreadState* state = thread->jvmti_thread_state();
- if (state == NULL || !state->is_interp_only_mode()) {
- return;
- }
- state->incr_cur_stack_depth();
- if (state->is_enabled(JVMTI_EVENT_METHOD_ENTRY)) {
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_METHOD_ENTRY)) {
- EVT_TRACE(JVMTI_EVENT_METHOD_ENTRY, ("JVMTI [%s] Evt Method Entry sent %s.%s",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));
- JvmtiEnv *env = ets->get_env();
- JvmtiMethodEventMark jem(thread, mh);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventMethodEntry callback = env->callbacks()->MethodEntry;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_methodID());
- }
- }
- }
- }
- }
- void JvmtiExport::post_method_exit(JavaThread *thread, Method* method, frame current_frame) {
- HandleMark hm(thread);
- methodHandle mh(thread, method);
- EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_EXIT, ("JVMTI [%s] Trg Method Exit triggered %s.%s",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL || !state->is_interp_only_mode()) {
- return;
- }
- bool exception_exit = state->is_exception_detected() && !state->is_exception_caught();
- if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) {
- Handle result;
- jvalue value;
- value.j = 0L;
- if (!exception_exit) {
- oop oop_result;
- BasicType type = current_frame.interpreter_frame_result(&oop_result, &value);
- if (type == T_OBJECT || type == T_ARRAY) {
- result = Handle(thread, oop_result);
- }
- }
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_METHOD_EXIT)) {
- EVT_TRACE(JVMTI_EVENT_METHOD_EXIT, ("JVMTI [%s] Evt Method Exit sent %s.%s",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));
- JvmtiEnv *env = ets->get_env();
- JvmtiMethodEventMark jem(thread, mh);
- if (result.not_null()) {
- value.l = JNIHandles::make_local(thread, result());
- }
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventMethodExit callback = env->callbacks()->MethodExit;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
- jem.jni_methodID(), exception_exit, value);
- }
- }
- }
- }
- if (state->is_enabled(JVMTI_EVENT_FRAME_POP)) {
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- int cur_frame_number = state->cur_stack_depth();
- if (ets->is_frame_pop(cur_frame_number)) {
- if (ets->is_enabled(JVMTI_EVENT_FRAME_POP)) {
- EVT_TRACE(JVMTI_EVENT_FRAME_POP, ("JVMTI [%s] Evt Frame Pop sent %s.%s",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));
- JvmtiEnv *env = ets->get_env();
- JvmtiMethodEventMark jem(thread, mh);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventFramePop callback = env->callbacks()->FramePop;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
- jem.jni_methodID(), exception_exit);
- }
- }
- ets->clear_frame_pop(cur_frame_number);
- }
- }
- }
- #ifdef AARCH64
- state->invalidate_cur_stack_depth();
- #else
- state->decr_cur_stack_depth();
- #endif
- }
- void JvmtiExport::post_single_step(JavaThread *thread, Method* method, address location) {
- HandleMark hm(thread);
- methodHandle mh(thread, method);
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_SINGLE_STEP);
- if (!ets->single_stepping_posted() && ets->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
- EVT_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Evt Single Step sent %s.%s @ %d",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
- location - mh()->code_base() ));
- JvmtiEnv *env = ets->get_env();
- JvmtiLocationEventMark jem(thread, mh, location);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventSingleStep callback = env->callbacks()->SingleStep;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
- jem.jni_methodID(), jem.location());
- }
- ets->set_single_stepping_posted();
- }
- }
- }
- void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, address location, oop exception) {
- HandleMark hm(thread);
- methodHandle mh(thread, method);
- Handle exception_handle(thread, exception);
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION, ("JVMTI [%s] Trg Exception thrown triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- if (!state->is_exception_detected()) {
- state->set_exception_detected();
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_EXCEPTION) && (exception != NULL)) {
- EVT_TRACE(JVMTI_EVENT_EXCEPTION,
- ("JVMTI [%s] Evt Exception thrown sent %s.%s @ %d",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
- location - mh()->code_base() ));
- JvmtiEnv *env = ets->get_env();
- JvmtiExceptionEventMark jem(thread, mh, location, exception_handle);
- EXCEPTION_MARK;
- bool should_repeat;
- vframeStream st(thread);
- assert(!st.at_end(), "cannot be at end");
- Method* current_method = NULL;
- methodHandle current_mh = methodHandle(thread, current_method);
- int current_bci = -1;
- do {
- current_method = st.method();
- current_mh = methodHandle(thread, current_method);
- current_bci = st.bci();
- do {
- should_repeat = false;
- KlassHandle eh_klass(thread, exception_handle()->klass());
- current_bci = Method::fast_exception_handler_bci_for(
- current_mh, eh_klass, current_bci, THREAD);
- if (HAS_PENDING_EXCEPTION) {
- exception_handle = Handle(thread, PENDING_EXCEPTION);
- CLEAR_PENDING_EXCEPTION;
- should_repeat = true;
- }
- } while (should_repeat && (current_bci != -1));
- st.next();
- } while ((current_bci < 0) && (!st.at_end()));
- jmethodID catch_jmethodID;
- if (current_bci < 0) {
- catch_jmethodID = 0;
- current_bci = 0;
- } else {
- catch_jmethodID = jem.to_jmethodID(current_mh);
- }
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventException callback = env->callbacks()->Exception;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
- jem.jni_methodID(), jem.location(),
- jem.exception(),
- catch_jmethodID, current_bci);
- }
- }
- }
- }
- state->invalidate_cur_stack_depth();
- }
- void JvmtiExport::notice_unwind_due_to_exception(JavaThread *thread, Method* method, address location, oop exception, bool in_handler_frame) {
- HandleMark hm(thread);
- methodHandle mh(thread, method);
- Handle exception_handle(thread, exception);
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION_CATCH,
- ("JVMTI [%s] Trg unwind_due_to_exception triggered %s.%s @ %s%d - %s",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
- location==0? "no location:" : "",
- location==0? 0 : location - mh()->code_base(),
- in_handler_frame? "in handler frame" : "not handler frame" ));
- if (state->is_exception_detected()) {
- state->invalidate_cur_stack_depth();
- if (!in_handler_frame) {
- if(state->is_interp_only_mode()) {
- JvmtiExport::post_method_exit(thread, method, thread->last_frame());
- state->invalidate_cur_stack_depth();
- }
- } else {
- assert(location != NULL, "must be a known location");
- assert(!state->is_exception_caught(), "exception must not be caught yet.");
- state->set_exception_caught();
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_EXCEPTION_CATCH) && (exception_handle() != NULL)) {
- EVT_TRACE(JVMTI_EVENT_EXCEPTION_CATCH,
- ("JVMTI [%s] Evt ExceptionCatch sent %s.%s @ %d",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
- location - mh()->code_base() ));
- JvmtiEnv *env = ets->get_env();
- JvmtiExceptionEventMark jem(thread, mh, location, exception_handle);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventExceptionCatch callback = env->callbacks()->ExceptionCatch;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
- jem.jni_methodID(), jem.location(),
- jem.exception());
- }
- }
- }
- }
- }
- }
- oop JvmtiExport::jni_GetField_probe(JavaThread *thread, jobject jobj, oop obj,
- Klass* klass, jfieldID fieldID, bool is_static) {
- if (*((int *)get_field_access_count_addr()) > 0 && thread->has_last_Java_frame()) {
- post_field_access_by_jni(thread, obj, klass, fieldID, is_static);
- if (jobj != NULL) return JNIHandles::resolve_non_null(jobj);
- }
- return obj;
- }
- oop JvmtiExport::jni_GetField_probe_nh(JavaThread *thread, jobject jobj, oop obj,
- Klass* klass, jfieldID fieldID, bool is_static) {
- if (*((int *)get_field_access_count_addr()) > 0 && thread->has_last_Java_frame()) {
- ResetNoHandleMark rnhm;
- post_field_access_by_jni(thread, obj, klass, fieldID, is_static);
- if (jobj != NULL) return JNIHandles::resolve_non_null(jobj);
- }
- return obj;
- }
- void JvmtiExport::post_field_access_by_jni(JavaThread *thread, oop obj,
- Klass* klass, jfieldID fieldID, bool is_static) {
- assert(thread->has_last_Java_frame(), "must be called with a Java context");
- ResourceMark rm;
- fieldDescriptor fd;
- bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);
- assert(valid_fieldID == true,"post_field_access_by_jni called with invalid fieldID");
- if (!valid_fieldID) return;
- if (!fd.is_field_access_watched()) return;
- HandleMark hm(thread);
- KlassHandle h_klass(thread, klass);
- Handle h_obj;
- if (!is_static) {
- assert(obj != NULL, "non-static needs an object");
- h_obj = Handle(thread, obj);
- }
- post_field_access(thread,
- thread->last_frame().interpreter_frame_method(),
- thread->last_frame().interpreter_frame_bcp(),
- h_klass, h_obj, fieldID);
- }
- void JvmtiExport::post_field_access(JavaThread *thread, Method* method,
- address location, KlassHandle field_klass, Handle object, jfieldID field) {
- HandleMark hm(thread);
- methodHandle mh(thread, method);
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("JVMTI [%s] Trg Field Access event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_FIELD_ACCESS)) {
- EVT_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("JVMTI [%s] Evt Field Access event sent %s.%s @ %d",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
- location - mh()->code_base() ));
- JvmtiEnv *env = ets->get_env();
- JvmtiLocationEventMark jem(thread, mh, location);
- jclass field_jclass = jem.to_jclass(field_klass());
- jobject field_jobject = jem.to_jobject(object());
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventFieldAccess callback = env->callbacks()->FieldAccess;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
- jem.jni_methodID(), jem.location(),
- field_jclass, field_jobject, field);
- }
- }
- }
- }
- oop JvmtiExport::jni_SetField_probe(JavaThread *thread, jobject jobj, oop obj,
- Klass* klass, jfieldID fieldID, bool is_static,
- char sig_type, jvalue *value) {
- if (*((int *)get_field_modification_count_addr()) > 0 && thread->has_last_Java_frame()) {
- post_field_modification_by_jni(thread, obj, klass, fieldID, is_static, sig_type, value);
- if (jobj != NULL) return JNIHandles::resolve_non_null(jobj);
- }
- return obj;
- }
- oop JvmtiExport::jni_SetField_probe_nh(JavaThread *thread, jobject jobj, oop obj,
- Klass* klass, jfieldID fieldID, bool is_static,
- char sig_type, jvalue *value) {
- if (*((int *)get_field_modification_count_addr()) > 0 && thread->has_last_Java_frame()) {
- ResetNoHandleMark rnhm;
- post_field_modification_by_jni(thread, obj, klass, fieldID, is_static, sig_type, value);
- if (jobj != NULL) return JNIHandles::resolve_non_null(jobj);
- }
- return obj;
- }
- void JvmtiExport::post_field_modification_by_jni(JavaThread *thread, oop obj,
- Klass* klass, jfieldID fieldID, bool is_static,
- char sig_type, jvalue *value) {
- assert(thread->has_last_Java_frame(), "must be called with Java context");
- ResourceMark rm;
- fieldDescriptor fd;
- bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);
- assert(valid_fieldID == true,"post_field_modification_by_jni called with invalid fieldID");
- if (!valid_fieldID) return;
- if (!fd.is_field_modification_watched()) return;
- HandleMark hm(thread);
- Handle h_obj;
- if (!is_static) {
- assert(obj != NULL, "non-static needs an object");
- h_obj = Handle(thread, obj);
- }
- KlassHandle h_klass(thread, klass);
- post_field_modification(thread,
- thread->last_frame().interpreter_frame_method(),
- thread->last_frame().interpreter_frame_bcp(),
- h_klass, h_obj, fieldID, sig_type, value);
- }
- void JvmtiExport::post_raw_field_modification(JavaThread *thread, Method* method,
- address location, KlassHandle field_klass, Handle object, jfieldID field,
- char sig_type, jvalue *value) {
- if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'B' || sig_type == 'C' || sig_type == 'S') {
- fieldDescriptor fd;
- bool found = JvmtiEnv::get_field_descriptor(field_klass(), field, &fd);
- if (found) {
- jint ival = value->i;
- switch (fd.field_type()) {
- case T_BOOLEAN:
- sig_type = 'Z';
- value->i = 0; // clear it
- value->z = (jboolean)ival;
- break;
- case T_BYTE:
- sig_type = 'B';
- value->i = 0; // clear it
- value->b = (jbyte)ival;
- break;
- case T_CHAR:
- sig_type = 'C';
- value->i = 0; // clear it
- value->c = (jchar)ival;
- break;
- case T_SHORT:
- sig_type = 'S';
- value->i = 0; // clear it
- value->s = (jshort)ival;
- break;
- case T_INT:
- break;
- default:
- ShouldNotReachHere();
- break;
- }
- }
- }
- assert(sig_type != '[', "array should have sig_type == 'L'");
- bool handle_created = false;
- if (sig_type == 'L') {
- handle_created = true;
- value->l = (jobject)JNIHandles::make_local(thread, (oop)value->l);
- }
- post_field_modification(thread, method, location, field_klass, object, field, sig_type, value);
- if (handle_created) {
- JNIHandles::destroy_local(value->l);
- }
- }
- void JvmtiExport::post_field_modification(JavaThread *thread, Method* method,
- address location, KlassHandle field_klass, Handle object, jfieldID field,
- char sig_type, jvalue *value_ptr) {
- HandleMark hm(thread);
- methodHandle mh(thread, method);
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,
- ("JVMTI [%s] Trg Field Modification event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_FIELD_MODIFICATION)) {
- EVT_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,
- ("JVMTI [%s] Evt Field Modification event sent %s.%s @ %d",
- JvmtiTrace::safe_get_thread_name(thread),
- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
- location - mh()->code_base() ));
- JvmtiEnv *env = ets->get_env();
- JvmtiLocationEventMark jem(thread, mh, location);
- jclass field_jclass = jem.to_jclass(field_klass());
- jobject field_jobject = jem.to_jobject(object());
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventFieldModification callback = env->callbacks()->FieldModification;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
- jem.jni_methodID(), jem.location(),
- field_jclass, field_jobject, field, sig_type, *value_ptr);
- }
- }
- }
- }
- void JvmtiExport::post_native_method_bind(Method* method, address* function_ptr) {
- JavaThread* thread = JavaThread::current();
- assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
- HandleMark hm(thread);
- methodHandle mh(thread, method);
- EVT_TRIG_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("JVMTI [%s] Trg Native Method Bind event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- if (JvmtiEventController::is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {
- EVT_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("JVMTI [%s] Evt Native Method Bind event sent",
- JvmtiTrace::safe_get_thread_name(thread) ));
- JvmtiMethodEventMark jem(thread, mh);
- JvmtiJavaThreadEventTransition jet(thread);
- JNIEnv* jni_env = JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL? NULL : jem.jni_env();
- jvmtiEventNativeMethodBind callback = env->callbacks()->NativeMethodBind;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jni_env, jem.jni_thread(),
- jem.jni_methodID(), (void*)(*function_ptr), (void**)function_ptr);
- }
- }
- }
- }
- }
- jvmtiCompiledMethodLoadInlineRecord* create_inline_record(nmethod* nm) {
- jint numstackframes = 0;
- jvmtiCompiledMethodLoadInlineRecord* record = (jvmtiCompiledMethodLoadInlineRecord*)NEW_RESOURCE_OBJ(jvmtiCompiledMethodLoadInlineRecord);
- record->header.kind = JVMTI_CMLR_INLINE_INFO;
- record->header.next = NULL;
- record->header.majorinfoversion = JVMTI_CMLR_MAJOR_VERSION_1;
- record->header.minorinfoversion = JVMTI_CMLR_MINOR_VERSION_0;
- record->numpcs = 0;
- for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) {
- if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue;
- record->numpcs++;
- }
- record->pcinfo = (PCStackInfo*)(NEW_RESOURCE_ARRAY(PCStackInfo, record->numpcs));
- int scope = 0;
- for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) {
- if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue;
- void* pc_address = (void*)p->real_pc(nm);
- assert(pc_address != NULL, "pc_address must be non-null");
- record->pcinfo[scope].pc = pc_address;
- numstackframes=0;
- for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) {
- numstackframes++;
- }
- assert(numstackframes != 0, "numstackframes must be nonzero.");
- record->pcinfo[scope].methods = (jmethodID *)NEW_RESOURCE_ARRAY(jmethodID, numstackframes);
- record->pcinfo[scope].bcis = (jint *)NEW_RESOURCE_ARRAY(jint, numstackframes);
- record->pcinfo[scope].numstackframes = numstackframes;
- int stackframe = 0;
- for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) {
- assert(sd->method() != NULL, "sd->method() cannot be null.");
- record->pcinfo[scope].methods[stackframe] = sd->method()->jmethod_id();
- record->pcinfo[scope].bcis[stackframe] = sd->bci();
- stackframe++;
- }
- scope++;
- }
- return record;
- }
- void JvmtiExport::post_compiled_method_load(nmethod *nm) {
- JavaThread* thread = JavaThread::current();
- EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
- ("JVMTI [%s] method compile load event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) {
- EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
- ("JVMTI [%s] class compile method load event sent %s.%s ",
- JvmtiTrace::safe_get_thread_name(thread),
- (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(),
- (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));
- ResourceMark rm(thread);
- HandleMark hm(thread);
- jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm);
- JvmtiCompiledMethodLoadEventMark jem(thread, nm, inlinerecord);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_methodID(),
- jem.code_size(), jem.code_data(), jem.map_length(),
- jem.map(), jem.compile_info());
- }
- }
- }
- }
- void JvmtiExport::post_compiled_method_load(JvmtiEnv* env, const jmethodID method, const jint length,
- const void *code_begin, const jint map_length,
- const jvmtiAddrLocationMap* map)
- {
- JavaThread* thread = JavaThread::current();
- EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
- ("JVMTI [%s] method compile load event triggered (by GenerateEvents)",
- JvmtiTrace::safe_get_thread_name(thread)));
- if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) {
- EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
- ("JVMTI [%s] class compile method load event sent (by GenerateEvents), jmethodID=" PTR_FORMAT,
- JvmtiTrace::safe_get_thread_name(thread), method));
- JvmtiEventMark jem(thread);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), method,
- length, code_begin, map_length,
- map, NULL);
- }
- }
- }
- void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) {
- assert(name != NULL && name[0] != '\0', "sanity check");
- JavaThread* thread = JavaThread::current();
- ThreadInVMfromUnknown __tiv;
- EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
- ("JVMTI [%s] method dynamic code generated event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_DYNAMIC_CODE_GENERATED)) {
- EVT_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
- ("JVMTI [%s] dynamic code generated event sent for %s",
- JvmtiTrace::safe_get_thread_name(thread), name));
- JvmtiEventMark jem(thread);
- JvmtiJavaThreadEventTransition jet(thread);
- jint length = (jint)pointer_delta(code_end, code_begin, sizeof(char));
- jvmtiEventDynamicCodeGenerated callback = env->callbacks()->DynamicCodeGenerated;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), name, (void*)code_begin, length);
- }
- }
- }
- }
- void JvmtiExport::post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) {
- jvmtiPhase phase = JvmtiEnv::get_phase();
- if (phase == JVMTI_PHASE_PRIMORDIAL || phase == JVMTI_PHASE_START) {
- post_dynamic_code_generated_internal(name, code_begin, code_end);
- } else {
- MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
- JvmtiDeferredEvent event = JvmtiDeferredEvent::dynamic_code_generated_event(
- name, code_begin, code_end);
- JvmtiDeferredEventQueue::enqueue(event);
- }
- }
- void JvmtiExport::post_dynamic_code_generated(JvmtiEnv* env, const char *name,
- const void *code_begin, const void *code_end)
- {
- JavaThread* thread = JavaThread::current();
- EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
- ("JVMTI [%s] dynamic code generated event triggered (by GenerateEvents)",
- JvmtiTrace::safe_get_thread_name(thread)));
- if (env->is_enabled(JVMTI_EVENT_DYNAMIC_CODE_GENERATED)) {
- EVT_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
- ("JVMTI [%s] dynamic code generated event sent for %s",
- JvmtiTrace::safe_get_thread_name(thread), name));
- JvmtiEventMark jem(thread);
- JvmtiJavaThreadEventTransition jet(thread);
- jint length = (jint)pointer_delta(code_end, code_begin, sizeof(char));
- jvmtiEventDynamicCodeGenerated callback = env->callbacks()->DynamicCodeGenerated;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), name, (void*)code_begin, length);
- }
- }
- }
- void JvmtiExport::post_dynamic_code_generated_while_holding_locks(const char* name,
- address code_begin, address code_end)
- {
- JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current());
- guarantee(state != NULL, "attempt to register stub via an exiting thread");
- JvmtiDynamicCodeEventCollector* collector = state->get_dynamic_code_event_collector();
- guarantee(collector != NULL, "attempt to register stub without event collector");
- collector->register_stub(name, code_begin, code_end);
- }
- void JvmtiExport::record_vm_internal_object_allocation(oop obj) {
- Thread* thread = ThreadLocalStorage::thread();
- if (thread != NULL && thread->is_Java_thread()) {
- No_Safepoint_Verifier no_sfpt;
- JvmtiThreadState *state = ((JavaThread*)thread)->jvmti_thread_state();
- if (state != NULL ) {
- JvmtiVMObjectAllocEventCollector *collector;
- collector = state->get_vm_object_alloc_event_collector();
- if (collector != NULL && collector->is_enabled()) {
- if (obj->klass() != SystemDictionary::Class_klass()) {
- collector->record_allocation(obj);
- }
- }
- }
- }
- }
- void JvmtiExport::post_garbage_collection_finish() {
- Thread *thread = Thread::current(); // this event is posted from VM-Thread.
- EVT_TRIG_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH,
- ("JVMTI [%s] garbage collection finish event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH)) {
- EVT_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH,
- ("JVMTI [%s] garbage collection finish event sent ",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiThreadEventTransition jet(thread);
- jvmtiEventGarbageCollectionFinish callback = env->callbacks()->GarbageCollectionFinish;
- if (callback != NULL) {
- (*callback)(env->jvmti_external());
- }
- }
- }
- }
- void JvmtiExport::post_garbage_collection_start() {
- Thread* thread = Thread::current(); // this event is posted from vm-thread.
- EVT_TRIG_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_START,
- ("JVMTI [%s] garbage collection start event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_GARBAGE_COLLECTION_START)) {
- EVT_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_START,
- ("JVMTI [%s] garbage collection start event sent ",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiThreadEventTransition jet(thread);
- jvmtiEventGarbageCollectionStart callback = env->callbacks()->GarbageCollectionStart;
- if (callback != NULL) {
- (*callback)(env->jvmti_external());
- }
- }
- }
- }
- void JvmtiExport::post_data_dump() {
- Thread *thread = Thread::current();
- EVT_TRIG_TRACE(JVMTI_EVENT_DATA_DUMP_REQUEST,
- ("JVMTI [%s] data dump request event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_DATA_DUMP_REQUEST)) {
- EVT_TRACE(JVMTI_EVENT_DATA_DUMP_REQUEST,
- ("JVMTI [%s] data dump request event sent ",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiThreadEventTransition jet(thread);
- jvmtiEventDataDumpRequest callback = env->callbacks()->DataDumpRequest;
- if (callback != NULL) {
- (*callback)(env->jvmti_external());
- }
- }
- }
- }
- void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) {
- oop object = (oop)obj_mntr->object();
- if (!ServiceUtil::visible_oop(object)) {
- return;
- }
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- HandleMark hm(thread);
- Handle h(thread, object);
- EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER,
- ("JVMTI [%s] montior contended enter event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_MONITOR_CONTENDED_ENTER)) {
- EVT_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER,
- ("JVMTI [%s] monitor contended enter event sent",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiMonitorEventMark jem(thread, h());
- JvmtiEnv *env = ets->get_env();
- JvmtiThreadEventTransition jet(thread);
- jvmtiEventMonitorContendedEnter callback = env->callbacks()->MonitorContendedEnter;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_object());
- }
- }
- }
- }
- void JvmtiExport::post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) {
- oop object = (oop)obj_mntr->object();
- if (!ServiceUtil::visible_oop(object)) {
- return;
- }
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- HandleMark hm(thread);
- Handle h(thread, object);
- EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,
- ("JVMTI [%s] montior contended entered event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED)) {
- EVT_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,
- ("JVMTI [%s] monitor contended enter event sent",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiMonitorEventMark jem(thread, h());
- JvmtiEnv *env = ets->get_env();
- JvmtiThreadEventTransition jet(thread);
- jvmtiEventMonitorContendedEntered callback = env->callbacks()->MonitorContendedEntered;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_object());
- }
- }
- }
- }
- void JvmtiExport::post_monitor_wait(JavaThread *thread, oop object,
- jlong timeout) {
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- HandleMark hm(thread);
- Handle h(thread, object);
- EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAIT,
- ("JVMTI [%s] montior wait event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_MONITOR_WAIT)) {
- EVT_TRACE(JVMTI_EVENT_MONITOR_WAIT,
- ("JVMTI [%s] monitor wait event sent ",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiMonitorEventMark jem(thread, h());
- JvmtiEnv *env = ets->get_env();
- JvmtiThreadEventTransition jet(thread);
- jvmtiEventMonitorWait callback = env->callbacks()->MonitorWait;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
- jem.jni_object(), timeout);
- }
- }
- }
- }
- void JvmtiExport::post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) {
- oop object = (oop)obj_mntr->object();
- if (!ServiceUtil::visible_oop(object)) {
- return;
- }
- JvmtiThreadState *state = thread->jvmti_thread_state();
- if (state == NULL) {
- return;
- }
- HandleMark hm(thread);
- Handle h(thread, object);
- EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAITED,
- ("JVMTI [%s] montior waited event triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiEnvThreadStateIterator it(state);
- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
- if (ets->is_enabled(JVMTI_EVENT_MONITOR_WAITED)) {
- EVT_TRACE(JVMTI_EVENT_MONITOR_WAITED,
- ("JVMTI [%s] monitor waited event sent ",
- JvmtiTrace::safe_get_thread_name(thread)));
- JvmtiMonitorEventMark jem(thread, h());
- JvmtiEnv *env = ets->get_env();
- JvmtiThreadEventTransition jet(thread);
- jvmtiEventMonitorWaited callback = env->callbacks()->MonitorWaited;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
- jem.jni_object(), timed_out);
- }
- }
- }
- }
- void JvmtiExport::post_vm_object_alloc(JavaThread *thread, oop object) {
- EVT_TRIG_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("JVMTI [%s] Trg vm object alloc triggered",
- JvmtiTrace::safe_get_thread_name(thread)));
- if (object == NULL) {
- return;
- }
- HandleMark hm(thread);
- Handle h(thread, object);
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_VM_OBJECT_ALLOC)) {
- EVT_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("JVMTI [%s] Evt vmobject alloc sent %s",
- JvmtiTrace::safe_get_thread_name(thread),
- object==NULL? "NULL" : java_lang_Class::as_Klass(object)->external_name()));
- JvmtiVMObjectAllocEventMark jem(thread, h());
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventVMObjectAlloc callback = env->callbacks()->VMObjectAlloc;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
- jem.jni_jobject(), jem.jni_class(), jem.size());
- }
- }
- }
- }
- void JvmtiExport::cleanup_thread(JavaThread* thread) {
- assert(JavaThread::current() == thread, "thread is not current");
- MutexLocker mu(JvmtiThreadState_lock);
- if (thread->jvmti_thread_state() != NULL) {
- JvmtiEventController::thread_ended(thread);
- }
- }
- void JvmtiExport::clear_detected_exception(JavaThread* thread) {
- assert(JavaThread::current() == thread, "thread is not current");
- JvmtiThreadState* state = thread->jvmti_thread_state();
- if (state != NULL) {
- state->clear_exception_detected();
- }
- }
- void JvmtiExport::oops_do(OopClosure* f) {
- JvmtiCurrentBreakpoints::oops_do(f);
- JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(f);
- }
- void JvmtiExport::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
- JvmtiTagMap::weak_oops_do(is_alive, f);
- }
- void JvmtiExport::gc_epilogue() {
- JvmtiCurrentBreakpoints::gc_epilogue();
- }
- void JvmtiExport::transition_pending_onload_raw_monitors() {
- JvmtiPendingMonitors::transition_raw_monitors();
- }
- extern "C" {
- typedef jint (JNICALL *OnAttachEntry_t)(JavaVM*, char *, void *);
- }
- jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) {
- char ebuf[1024];
- char buffer[JVM_MAXPATHLEN];
- void* library = NULL;
- jint result = JNI_ERR;
- const char *on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS;
- size_t num_symbol_entries = ARRAY_SIZE(on_attach_symbols);
- const char* agent = op->arg(0);
- const char* absParam = op->arg(1);
- const char* options = op->arg(2);
- bool is_absolute_path = (absParam != NULL) && (strcmp(absParam,"true")==0);
- AgentLibrary *agent_lib = new AgentLibrary(agent, options, is_absolute_path, NULL);
- if (!os::find_builtin_agent(agent_lib, on_attach_symbols, num_symbol_entries)) {
- if (is_absolute_path) {
- library = os::dll_load(agent, ebuf, sizeof ebuf);
- } else {
- if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
- agent)) {
- library = os::dll_load(buffer, ebuf, sizeof ebuf);
- }
- if (library == NULL) {
- char ns[1] = {0};
- if (os::dll_build_name(buffer, sizeof(buffer), ns, agent)) {
- library = os::dll_load(buffer, ebuf, sizeof ebuf);
- }
- }
- }
- if (library != NULL) {
- agent_lib->set_os_lib(library);
- agent_lib->set_valid();
- }
- }
- if (agent_lib->valid()) {
- OnAttachEntry_t on_attach_entry = NULL;
- on_attach_entry = CAST_TO_FN_PTR(OnAttachEntry_t,
- os::find_agent_function(agent_lib, false, on_attach_symbols, num_symbol_entries));
- if (on_attach_entry == NULL) {
- if (!agent_lib->is_static_lib()) {
- os::dll_unload(library);
- }
- delete agent_lib;
- } else {
- JavaThread* THREAD = JavaThread::current();
- {
- extern struct JavaVM_ main_vm;
- JvmtiThreadEventMark jem(THREAD);
- JvmtiJavaThreadEventTransition jet(THREAD);
- result = (*on_attach_entry)(&main_vm, (char*)options, NULL);
- }
- if (HAS_PENDING_EXCEPTION) {
- CLEAR_PENDING_EXCEPTION;
- }
- if (result == JNI_OK) {
- Arguments::add_loaded_agent(agent_lib);
- } else {
- delete agent_lib;
- }
- st->print_cr("%d", result);
- result = JNI_OK;
- }
- }
- return result;
- }
- void JvmtiEventCollector::setup_jvmti_thread_state() {
- JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current());
- guarantee(state != NULL, "exiting thread called setup_jvmti_thread_state");
- if (is_vm_object_alloc_event()) {
- _prev = state->get_vm_object_alloc_event_collector();
- state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)this);
- } else if (is_dynamic_code_event()) {
- _prev = state->get_dynamic_code_event_collector();
- state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)this);
- }
- }
- void JvmtiEventCollector::unset_jvmti_thread_state() {
- JvmtiThreadState* state = JavaThread::current()->jvmti_thread_state();
- if (state != NULL) {
- if (is_vm_object_alloc_event()) {
- if (state->get_vm_object_alloc_event_collector() == this) {
- state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)_prev);
- } else {
- }
- } else {
- if (is_dynamic_code_event()) {
- if (state->get_dynamic_code_event_collector() == this) {
- state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)_prev);
- } else {
- }
- }
- }
- }
- }
- JvmtiDynamicCodeEventCollector::JvmtiDynamicCodeEventCollector() : _code_blobs(NULL) {
- if (JvmtiExport::should_post_dynamic_code_generated()) {
- setup_jvmti_thread_state();
- }
- }
- JvmtiDynamicCodeEventCollector::~JvmtiDynamicCodeEventCollector() {
- assert(!JavaThread::current()->owns_locks(), "all locks must be released to post deferred events");
- if (_code_blobs != NULL) {
- for (int i=0; i<_code_blobs->length(); i++) {
- JvmtiCodeBlobDesc* blob = _code_blobs->at(i);
- JvmtiExport::post_dynamic_code_generated(blob->name(), blob->code_begin(), blob->code_end());
- FreeHeap(blob);
- }
- delete _code_blobs;
- }
- unset_jvmti_thread_state();
- }
- void JvmtiDynamicCodeEventCollector::register_stub(const char* name, address start, address end) {
- if (_code_blobs == NULL) {
- _code_blobs = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiCodeBlobDesc*>(1,true);
- }
- _code_blobs->append(new JvmtiCodeBlobDesc(name, start, end));
- }
- JvmtiVMObjectAllocEventCollector::JvmtiVMObjectAllocEventCollector() : _allocated(NULL) {
- if (JvmtiExport::should_post_vm_object_alloc()) {
- _enable = true;
- setup_jvmti_thread_state();
- } else {
- _enable = false;
- }
- }
- JvmtiVMObjectAllocEventCollector::~JvmtiVMObjectAllocEventCollector() {
- if (_allocated != NULL) {
- set_enabled(false);
- for (int i = 0; i < _allocated->length(); i++) {
- oop obj = _allocated->at(i);
- if (ServiceUtil::visible_oop(obj)) {
- JvmtiExport::post_vm_object_alloc(JavaThread::current(), obj);
- }
- }
- delete _allocated;
- }
- unset_jvmti_thread_state();
- }
- void JvmtiVMObjectAllocEventCollector::record_allocation(oop obj) {
- assert(is_enabled(), "VM object alloc event collector is not enabled");
- if (_allocated == NULL) {
- _allocated = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(1, true);
- }
- _allocated->push(obj);
- }
- void JvmtiVMObjectAllocEventCollector::oops_do(OopClosure* f) {
- if (_allocated != NULL) {
- for(int i=_allocated->length() - 1; i >= 0; i--) {
- if (_allocated->at(i) != NULL) {
- f->do_oop(_allocated->adr_at(i));
- }
- }
- }
- }
- void JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(OopClosure* f) {
- if (!JvmtiEnv::environments_might_exist()) {
- return;
- }
- for (JavaThread *jthr = Threads::first(); jthr != NULL; jthr = jthr->next()) {
- JvmtiThreadState *state = jthr->jvmti_thread_state();
- if (state != NULL) {
- JvmtiVMObjectAllocEventCollector *collector;
- collector = state->get_vm_object_alloc_event_collector();
- while (collector != NULL) {
- collector->oops_do(f);
- collector = (JvmtiVMObjectAllocEventCollector *)collector->get_prev();
- }
- }
- }
- }
- NoJvmtiVMObjectAllocMark::NoJvmtiVMObjectAllocMark() : _collector(NULL) {
- if (!JvmtiExport::should_post_vm_object_alloc()) {
- return;
- }
- Thread* thread = ThreadLocalStorage::thread();
- if (thread != NULL && thread->is_Java_thread()) {
- JavaThread* current_thread = (JavaThread*)thread;
- JvmtiThreadState *state = current_thread->jvmti_thread_state();
- if (state != NULL) {
- JvmtiVMObjectAllocEventCollector *collector;
- collector = state->get_vm_object_alloc_event_collector();
- if (collector != NULL && collector->is_enabled()) {
- _collector = collector;
- _collector->set_enabled(false);
- }
- }
- }
- }
- NoJvmtiVMObjectAllocMark::~NoJvmtiVMObjectAllocMark() {
- if (was_enabled()) {
- _collector->set_enabled(true);
- }
- };
- JvmtiGCMarker::JvmtiGCMarker() {
- if (!JvmtiEnv::environments_might_exist()) {
- return;
- }
- if (JvmtiExport::should_post_garbage_collection_start()) {
- JvmtiExport::post_garbage_collection_start();
- }
- if (SafepointSynchronize::is_at_safepoint()) {
- JvmtiEnvBase::check_for_periodic_clean_up();
- }
- }
- JvmtiGCMarker::~JvmtiGCMarker() {
- if (!JvmtiEnv::environments_might_exist()) {
- return;
- }
- if (JvmtiExport::should_post_garbage_collection_finish()) {
- JvmtiExport::post_garbage_collection_finish();
- }
- }
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiExport.hpp
- #ifndef SHARE_VM_PRIMS_JVMTIEXPORT_HPP
- #define SHARE_VM_PRIMS_JVMTIEXPORT_HPP
- #include "jvmtifiles/jvmti.h"
- #include "memory/allocation.hpp"
- #include "memory/iterator.hpp"
- #include "oops/oop.hpp"
- #include "oops/oopsHierarchy.hpp"
- #include "runtime/frame.hpp"
- #include "runtime/handles.hpp"
- #include "utilities/globalDefinitions.hpp"
- #include "utilities/growableArray.hpp"
- #include "utilities/macros.hpp"
- #include "code/jvmticmlr.h"
- class JvmtiEventControllerPrivate;
- class JvmtiManageCapabilities;
- class JvmtiEnv;
- class JvmtiThreadState;
- class AttachOperation;
- #define JVMTI_SUPPORT_FLAG(key) \
- private: \
- static bool _##key; \
- public: \
- inline static void set_##key(bool on) { \
- JVMTI_ONLY(_##key = (on != 0)); \
- NOT_JVMTI(report_unsupported(on)); \
- } \
- inline static bool key() { \
- JVMTI_ONLY(return _##key); \
- NOT_JVMTI(return false); \
- }
- class JvmtiExport : public AllStatic {
- friend class VMStructs;
- friend class CompileReplay;
- private:
- #if INCLUDE_JVMTI
- static int _field_access_count;
- static int _field_modification_count;
- static bool _can_access_local_variables;
- static bool _can_hotswap_or_post_breakpoint;
- static bool _can_modify_any_class;
- static bool _can_walk_any_space;
- #endif // INCLUDE_JVMTI
- JVMTI_SUPPORT_FLAG(can_get_source_debug_extension)
- JVMTI_SUPPORT_FLAG(can_maintain_original_method_order)
- JVMTI_SUPPORT_FLAG(can_post_interpreter_events)
- JVMTI_SUPPORT_FLAG(can_post_on_exceptions)
- JVMTI_SUPPORT_FLAG(can_post_breakpoint)
- JVMTI_SUPPORT_FLAG(can_post_field_access)
- JVMTI_SUPPORT_FLAG(can_post_field_modification)
- JVMTI_SUPPORT_FLAG(can_post_method_entry)
- JVMTI_SUPPORT_FLAG(can_post_method_exit)
- JVMTI_SUPPORT_FLAG(can_pop_frame)
- JVMTI_SUPPORT_FLAG(can_force_early_return)
- friend class JvmtiEventControllerPrivate; // should only modify these flags
- JVMTI_SUPPORT_FLAG(should_post_single_step)
- JVMTI_SUPPORT_FLAG(should_post_field_access)
- JVMTI_SUPPORT_FLAG(should_post_field_modification)
- JVMTI_SUPPORT_FLAG(should_post_class_load)
- JVMTI_SUPPORT_FLAG(should_post_class_prepare)
- JVMTI_SUPPORT_FLAG(should_post_class_unload)
- JVMTI_SUPPORT_FLAG(should_post_native_method_bind)
- JVMTI_SUPPORT_FLAG(should_post_compiled_method_load)
- JVMTI_SUPPORT_FLAG(should_post_compiled_method_unload)
- JVMTI_SUPPORT_FLAG(should_post_dynamic_code_generated)
- JVMTI_SUPPORT_FLAG(should_post_monitor_contended_enter)
- JVMTI_SUPPORT_FLAG(should_post_monitor_contended_entered)
- JVMTI_SUPPORT_FLAG(should_post_monitor_wait)
- JVMTI_SUPPORT_FLAG(should_post_monitor_waited)
- JVMTI_SUPPORT_FLAG(should_post_data_dump)
- JVMTI_SUPPORT_FLAG(should_post_garbage_collection_start)
- JVMTI_SUPPORT_FLAG(should_post_garbage_collection_finish)
- JVMTI_SUPPORT_FLAG(should_post_on_exceptions)
- JVMTI_SUPPORT_FLAG(should_post_thread_life)
- JVMTI_SUPPORT_FLAG(should_post_object_free)
- JVMTI_SUPPORT_FLAG(should_post_resource_exhausted)
- JVMTI_SUPPORT_FLAG(should_clean_up_heap_objects)
- JVMTI_SUPPORT_FLAG(should_post_vm_object_alloc)
- static void report_unsupported(bool on);
- friend class JvmtiManageCapabilities;
- inline static void set_can_modify_any_class(bool on) {
- JVMTI_ONLY(_can_modify_any_class = (on != 0);)
- }
- inline static void set_can_access_local_variables(bool on) {
- JVMTI_ONLY(_can_access_local_variables = (on != 0);)
- }
- inline static void set_can_hotswap_or_post_breakpoint(bool on) {
- JVMTI_ONLY(_can_hotswap_or_post_breakpoint = (on != 0);)
- }
- inline static void set_can_walk_any_space(bool on) {
- JVMTI_ONLY(_can_walk_any_space = (on != 0);)
- }
- enum {
- JVMTI_VERSION_MASK = 0x70000000,
- JVMTI_VERSION_VALUE = 0x30000000,
- JVMDI_VERSION_VALUE = 0x20000000
- };
- static void post_field_modification(JavaThread *thread, Method* method, address location,
- KlassHandle field_klass, Handle object, jfieldID field,
- char sig_type, jvalue *value);
- static void post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) NOT_JVMTI_RETURN;
- private:
- friend class JvmtiCodeBlobEvents;
- static void post_compiled_method_load(JvmtiEnv* env, const jmethodID method, const jint length,
- const void *code_begin, const jint map_length,
- const jvmtiAddrLocationMap* map) NOT_JVMTI_RETURN;
- static void post_dynamic_code_generated(JvmtiEnv* env, const char *name, const void *code_begin,
- const void *code_end) NOT_JVMTI_RETURN;
- static bool _has_redefined_a_class;
- friend class VM_RedefineClasses;
- inline static void set_has_redefined_a_class() {
- JVMTI_ONLY(_has_redefined_a_class = true;)
- }
- static bool _all_dependencies_are_recorded;
- public:
- inline static bool has_redefined_a_class() {
- JVMTI_ONLY(return _has_redefined_a_class);
- NOT_JVMTI(return false);
- }
- inline static bool all_dependencies_are_recorded() {
- return _all_dependencies_are_recorded;
- }
- inline static void set_all_dependencies_are_recorded(bool on) {
- _all_dependencies_are_recorded = (on != 0);
- }
- static void enter_onload_phase() NOT_JVMTI_RETURN;
- static void enter_primordial_phase() NOT_JVMTI_RETURN;
- static void enter_start_phase() NOT_JVMTI_RETURN;
- static void enter_live_phase() NOT_JVMTI_RETURN;
- inline static bool can_modify_any_class() {
- JVMTI_ONLY(return _can_modify_any_class);
- NOT_JVMTI(return false);
- }
- inline static bool can_access_local_variables() {
- JVMTI_ONLY(return _can_access_local_variables);
- NOT_JVMTI(return false);
- }
- inline static bool can_hotswap_or_post_breakpoint() {
- JVMTI_ONLY(return _can_hotswap_or_post_breakpoint);
- NOT_JVMTI(return false);
- }
- inline static bool can_walk_any_space() {
- JVMTI_ONLY(return _can_walk_any_space);
- NOT_JVMTI(return false);
- }
- static address get_field_access_count_addr() NOT_JVMTI_RETURN_(0);
- static address get_field_modification_count_addr() NOT_JVMTI_RETURN_(0);
- static bool is_jvmti_version(jint version) {
- JVMTI_ONLY(return (version & JVMTI_VERSION_MASK) == JVMTI_VERSION_VALUE);
- NOT_JVMTI(return false);
- }
- static bool is_jvmdi_version(jint version) {
- JVMTI_ONLY(return (version & JVMTI_VERSION_MASK) == JVMDI_VERSION_VALUE);
- NOT_JVMTI(return false);
- }
- static jint get_jvmti_interface(JavaVM *jvm, void **penv, jint version) NOT_JVMTI_RETURN_(0);
- static void decode_version_values(jint version, int * major, int * minor,
- int * micro) NOT_JVMTI_RETURN;
- static void at_single_stepping_point(JavaThread *thread, Method* method, address location) NOT_JVMTI_RETURN;
- static void expose_single_stepping(JavaThread *thread) NOT_JVMTI_RETURN;
- static bool hide_single_stepping(JavaThread *thread) NOT_JVMTI_RETURN_(false);
- static void post_vm_start () NOT_JVMTI_RETURN;
- static void post_vm_initialized () NOT_JVMTI_RETURN;
- static void post_vm_death () NOT_JVMTI_RETURN;
- static void post_single_step (JavaThread *thread, Method* method, address location) NOT_JVMTI_RETURN;
- static void post_raw_breakpoint (JavaThread *thread, Method* method, address location) NOT_JVMTI_RETURN;
- static void post_exception_throw (JavaThread *thread, Method* method, address location, oop exception) NOT_JVMTI_RETURN;
- static void notice_unwind_due_to_exception (JavaThread *thread, Method* method, address location, oop exception, bool in_handler_frame) NOT_JVMTI_RETURN;
- static oop jni_GetField_probe (JavaThread *thread, jobject jobj,
- oop obj, Klass* klass, jfieldID fieldID, bool is_static)
- NOT_JVMTI_RETURN_(NULL);
- static oop jni_GetField_probe_nh (JavaThread *thread, jobject jobj,
- oop obj, Klass* klass, jfieldID fieldID, bool is_static)
- NOT_JVMTI_RETURN_(NULL);
- static void post_field_access_by_jni (JavaThread *thread, oop obj,
- Klass* klass, jfieldID fieldID, bool is_static) NOT_JVMTI_RETURN;
- static void post_field_access (JavaThread *thread, Method* method,
- address location, KlassHandle field_klass, Handle object, jfieldID field) NOT_JVMTI_RETURN;
- static oop jni_SetField_probe (JavaThread *thread, jobject jobj,
- oop obj, Klass* klass, jfieldID fieldID, bool is_static, char sig_type,
- jvalue *value) NOT_JVMTI_RETURN_(NULL);
- static oop jni_SetField_probe_nh (JavaThread *thread, jobject jobj,
- oop obj, Klass* klass, jfieldID fieldID, bool is_static, char sig_type,
- jvalue *value) NOT_JVMTI_RETURN_(NULL);
- static void post_field_modification_by_jni(JavaThread *thread, oop obj,
- Klass* klass, jfieldID fieldID, bool is_static, char sig_type,
- jvalue *value);
- static void post_raw_field_modification(JavaThread *thread, Method* method,
- address location, KlassHandle field_klass, Handle object, jfieldID field,
- char sig_type, jvalue *value) NOT_JVMTI_RETURN;
- static void post_method_entry (JavaThread *thread, Method* method, frame current_frame) NOT_JVMTI_RETURN;
- static void post_method_exit (JavaThread *thread, Method* method, frame current_frame) NOT_JVMTI_RETURN;
- static void post_class_load (JavaThread *thread, Klass* klass) NOT_JVMTI_RETURN;
- static void post_class_unload (Klass* klass) NOT_JVMTI_RETURN;
- static void post_class_prepare (JavaThread *thread, Klass* klass) NOT_JVMTI_RETURN;
- static void post_thread_start (JavaThread *thread) NOT_JVMTI_RETURN;
- static void post_thread_end (JavaThread *thread) NOT_JVMTI_RETURN;
- static bool _should_post_class_file_load_hook;
- inline static void set_should_post_class_file_load_hook(bool on) { _should_post_class_file_load_hook = on; }
- inline static bool should_post_class_file_load_hook() {
- JVMTI_ONLY(return _should_post_class_file_load_hook);
- NOT_JVMTI(return false;)
- }
- static void post_class_file_load_hook(Symbol* h_name, Handle class_loader,
- Handle h_protection_domain,
- unsigned char **data_ptr, unsigned char **end_ptr,
- JvmtiCachedClassFileData **cache_ptr) NOT_JVMTI_RETURN;
- static void post_native_method_bind(Method* method, address* function_ptr) NOT_JVMTI_RETURN;
- static void post_compiled_method_load(nmethod *nm) NOT_JVMTI_RETURN;
- static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) NOT_JVMTI_RETURN;
- static void post_compiled_method_unload(jmethodID mid, const void *code_begin) NOT_JVMTI_RETURN;
- static void post_dynamic_code_generated_while_holding_locks(const char* name, address code_begin, address code_end) NOT_JVMTI_RETURN;
- static void post_garbage_collection_finish() NOT_JVMTI_RETURN;
- static void post_garbage_collection_start() NOT_JVMTI_RETURN;
- static void post_data_dump() NOT_JVMTI_RETURN;
- static void post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) NOT_JVMTI_RETURN;
- static void post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) NOT_JVMTI_RETURN;
- static void post_monitor_wait(JavaThread *thread, oop obj, jlong timeout) NOT_JVMTI_RETURN;
- static void post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) NOT_JVMTI_RETURN;
- static void post_object_free(JvmtiEnv* env, jlong tag) NOT_JVMTI_RETURN;
- static void post_resource_exhausted(jint resource_exhausted_flags, const char* detail) NOT_JVMTI_RETURN;
- static void record_vm_internal_object_allocation(oop object) NOT_JVMTI_RETURN;
- static void post_vm_object_alloc(JavaThread *thread, oop object) NOT_JVMTI_RETURN;
- inline static void vm_object_alloc_event_collector(oop object) {
- if (should_post_vm_object_alloc()) {
- record_vm_internal_object_allocation(object);
- }
- }
- inline static void post_array_size_exhausted() {
- if (should_post_resource_exhausted()) {
- post_resource_exhausted(JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
- "Requested array size exceeds VM limit");
- }
- }
- static void cleanup_thread (JavaThread* thread) NOT_JVMTI_RETURN;
- static void clear_detected_exception (JavaThread* thread) NOT_JVMTI_RETURN;
- static void oops_do(OopClosure* f) NOT_JVMTI_RETURN;
- static void weak_oops_do(BoolObjectClosure* b, OopClosure* f) NOT_JVMTI_RETURN;
- static void gc_epilogue() NOT_JVMTI_RETURN;
- static void transition_pending_onload_raw_monitors() NOT_JVMTI_RETURN;
- static jint load_agent_library(AttachOperation* op, outputStream* out) NOT_JVMTI_RETURN_(JNI_ERR);
- static char** get_all_native_method_prefixes(int* count_ptr) NOT_JVMTI_RETURN_(NULL);
- };
- class JvmtiCodeBlobDesc : public CHeapObj<mtInternal> {
- private:
- char _name[64];
- address _code_begin;
- address _code_end;
- public:
- JvmtiCodeBlobDesc(const char *name, address code_begin, address code_end) {
- assert(name != NULL, "all code blobs must be named");
- strncpy(_name, name, sizeof(_name) - 1);
- _name[sizeof(_name)-1] = '\0';
- _code_begin = code_begin;
- _code_end = code_end;
- }
- char* name() { return _name; }
- address code_begin() { return _code_begin; }
- address code_end() { return _code_end; }
- };
- class JvmtiEventCollector : public StackObj {
- private:
- JvmtiEventCollector* _prev; // Save previous one to support nested event collector.
- public:
- void setup_jvmti_thread_state(); // Set this collector in current thread.
- void unset_jvmti_thread_state(); // Reset previous collector in current thread.
- virtual bool is_dynamic_code_event() { return false; }
- virtual bool is_vm_object_alloc_event(){ return false; }
- JvmtiEventCollector *get_prev() { return _prev; }
- };
- class JvmtiDynamicCodeEventCollector : public JvmtiEventCollector {
- private:
- GrowableArray<JvmtiCodeBlobDesc*>* _code_blobs; // collected code blob events
- friend class JvmtiExport;
- void register_stub(const char* name, address start, address end);
- public:
- JvmtiDynamicCodeEventCollector() NOT_JVMTI_RETURN;
- ~JvmtiDynamicCodeEventCollector() NOT_JVMTI_RETURN;
- bool is_dynamic_code_event() { return true; }
- };
- class JvmtiVMObjectAllocEventCollector : public JvmtiEventCollector {
- private:
- GrowableArray<oop>* _allocated; // field to record vm internally allocated object oop.
- bool _enable; // This flag is enabled in constructor and disabled
- void oops_do(OopClosure* f);
- friend class JvmtiExport;
- inline void record_allocation(oop obj);
- static void oops_do_for_all_threads(OopClosure* f);
- public:
- JvmtiVMObjectAllocEventCollector() NOT_JVMTI_RETURN;
- ~JvmtiVMObjectAllocEventCollector() NOT_JVMTI_RETURN;
- bool is_vm_object_alloc_event() { return true; }
- bool is_enabled() { return _enable; }
- void set_enabled(bool on) { _enable = on; }
- };
- class NoJvmtiVMObjectAllocMark : public StackObj {
- private:
- JvmtiVMObjectAllocEventCollector *_collector;
- bool was_enabled() { return _collector != NULL; }
- public:
- NoJvmtiVMObjectAllocMark() NOT_JVMTI_RETURN;
- ~NoJvmtiVMObjectAllocMark() NOT_JVMTI_RETURN;
- };
- class JvmtiGCMarker : public StackObj {
- public:
- JvmtiGCMarker() NOT_JVMTI_RETURN;
- ~JvmtiGCMarker() NOT_JVMTI_RETURN;
- };
- class JvmtiHideSingleStepping : public StackObj {
- private:
- bool _single_step_hidden;
- JavaThread * _thread;
- public:
- JvmtiHideSingleStepping(JavaThread * thread) {
- assert(thread != NULL, "sanity check");
- _single_step_hidden = false;
- _thread = thread;
- if (JvmtiExport::should_post_single_step()) {
- _single_step_hidden = JvmtiExport::hide_single_stepping(_thread);
- }
- }
- ~JvmtiHideSingleStepping() {
- if (_single_step_hidden) {
- JvmtiExport::expose_single_stepping(_thread);
- }
- }
- };
- #endif // SHARE_VM_PRIMS_JVMTIEXPORT_HPP
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiExtensions.cpp
- #include "precompiled.hpp"
- #include "prims/jvmtiExport.hpp"
- #include "prims/jvmtiExtensions.hpp"
- GrowableArray<jvmtiExtensionFunctionInfo*>* JvmtiExtensions::_ext_functions;
- GrowableArray<jvmtiExtensionEventInfo*>* JvmtiExtensions::_ext_events;
- static jvmtiError JNICALL IsClassUnloadingEnabled(const jvmtiEnv* env, jboolean* enabled, ...) {
- if (enabled == NULL) {
- return JVMTI_ERROR_NULL_POINTER;
- }
- return JVMTI_ERROR_NONE;
- }
- void JvmtiExtensions::register_extensions() {
- _ext_functions = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiExtensionFunctionInfo*>(1,true);
- _ext_events = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiExtensionEventInfo*>(1,true);
- static jvmtiParamInfo func_params[] = {
- { (char*)"IsClassUnloadingEnabled", JVMTI_KIND_OUT, JVMTI_TYPE_JBOOLEAN, JNI_FALSE }
- };
- static jvmtiExtensionFunctionInfo ext_func = {
- (jvmtiExtensionFunction)IsClassUnloadingEnabled,
- (char*)"com.sun.hotspot.functions.IsClassUnloadingEnabled",
- (char*)"Tell if class unloading is enabled (-noclassgc)",
- sizeof(func_params)/sizeof(func_params[0]),
- func_params,
- 0, // no non-universal errors
- NULL
- };
- _ext_functions->append(&ext_func);
- static jvmtiParamInfo event_params[] = {
- { (char*)"JNI Environment", JVMTI_KIND_IN, JVMTI_TYPE_JNIENV, JNI_FALSE },
- { (char*)"Thread", JVMTI_KIND_IN, JVMTI_TYPE_JTHREAD, JNI_FALSE },
- { (char*)"Class", JVMTI_KIND_IN, JVMTI_TYPE_JCLASS, JNI_FALSE }
- };
- static jvmtiExtensionEventInfo ext_event = {
- EXT_EVENT_CLASS_UNLOAD,
- (char*)"com.sun.hotspot.events.ClassUnload",
- (char*)"CLASS_UNLOAD event",
- sizeof(event_params)/sizeof(event_params[0]),
- event_params
- };
- _ext_events->append(&ext_event);
- }
- jvmtiError JvmtiExtensions::get_functions(JvmtiEnv* env,
- jint* extension_count_ptr,
- jvmtiExtensionFunctionInfo** extensions)
- {
- guarantee(_ext_functions != NULL, "registration not done");
- ResourceTracker rt(env);
- jvmtiExtensionFunctionInfo* ext_funcs;
- jvmtiError err = rt.allocate(_ext_functions->length() *
- sizeof(jvmtiExtensionFunctionInfo),
- (unsigned char**)&ext_funcs);
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- for (int i=0; i<_ext_functions->length(); i++ ) {
- ext_funcs[i].func = _ext_functions->at(i)->func;
- char *id = _ext_functions->at(i)->id;
- err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_funcs[i].id));
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- strcpy(ext_funcs[i].id, id);
- char *desc = _ext_functions->at(i)->short_description;
- err = rt.allocate(strlen(desc)+1,
- (unsigned char**)&(ext_funcs[i].short_description));
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- strcpy(ext_funcs[i].short_description, desc);
- jint param_count = _ext_functions->at(i)->param_count;
- ext_funcs[i].param_count = param_count;
- if (param_count == 0) {
- ext_funcs[i].params = NULL;
- } else {
- err = rt.allocate(param_count*sizeof(jvmtiParamInfo),
- (unsigned char**)&(ext_funcs[i].params));
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- jvmtiParamInfo* src_params = _ext_functions->at(i)->params;
- jvmtiParamInfo* dst_params = ext_funcs[i].params;
- for (int j=0; j<param_count; j++) {
- err = rt.allocate(strlen(src_params[j].name)+1,
- (unsigned char**)&(dst_params[j].name));
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- strcpy(dst_params[j].name, src_params[j].name);
- dst_params[j].kind = src_params[j].kind;
- dst_params[j].base_type = src_params[j].base_type;
- dst_params[j].null_ok = src_params[j].null_ok;
- }
- }
- jint error_count = _ext_functions->at(i)->error_count;
- ext_funcs[i].error_count = error_count;
- if (error_count == 0) {
- ext_funcs[i].errors = NULL;
- } else {
- err = rt.allocate(error_count*sizeof(jvmtiError),
- (unsigned char**)&(ext_funcs[i].errors));
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- memcpy(ext_funcs[i].errors, _ext_functions->at(i)->errors,
- error_count*sizeof(jvmtiError));
- }
- }
- return JVMTI_ERROR_NONE;
- }
- jvmtiError JvmtiExtensions::get_events(JvmtiEnv* env,
- jint* extension_count_ptr,
- jvmtiExtensionEventInfo** extensions)
- {
- guarantee(_ext_events != NULL, "registration not done");
- ResourceTracker rt(env);
- jvmtiExtensionEventInfo* ext_events;
- jvmtiError err = rt.allocate(_ext_events->length() * sizeof(jvmtiExtensionEventInfo),
- (unsigned char**)&ext_events);
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- for (int i=0; i<_ext_events->length(); i++ ) {
- ext_events[i].extension_event_index = _ext_events->at(i)->extension_event_index;
- char *id = _ext_events->at(i)->id;
- err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_events[i].id));
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- strcpy(ext_events[i].id, id);
- char *desc = _ext_events->at(i)->short_description;
- err = rt.allocate(strlen(desc)+1,
- (unsigned char**)&(ext_events[i].short_description));
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- strcpy(ext_events[i].short_description, desc);
- jint param_count = _ext_events->at(i)->param_count;
- ext_events[i].param_count = param_count;
- if (param_count == 0) {
- ext_events[i].params = NULL;
- } else {
- err = rt.allocate(param_count*sizeof(jvmtiParamInfo),
- (unsigned char**)&(ext_events[i].params));
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- jvmtiParamInfo* src_params = _ext_events->at(i)->params;
- jvmtiParamInfo* dst_params = ext_events[i].params;
- for (int j=0; j<param_count; j++) {
- err = rt.allocate(strlen(src_params[j].name)+1,
- (unsigned char**)&(dst_params[j].name));
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- strcpy(dst_params[j].name, src_params[j].name);
- dst_params[j].kind = src_params[j].kind;
- dst_params[j].base_type = src_params[j].base_type;
- dst_params[j].null_ok = src_params[j].null_ok;
- }
- }
- }
- return JVMTI_ERROR_NONE;
- }
- jvmtiError JvmtiExtensions::set_event_callback(JvmtiEnv* env,
- jint extension_event_index,
- jvmtiExtensionEvent callback)
- {
- guarantee(_ext_events != NULL, "registration not done");
- jvmtiExtensionEventInfo* event = NULL;
- if (_ext_events != NULL) {
- for (int i=0; i<_ext_events->length(); i++ ) {
- if (_ext_events->at(i)->extension_event_index == extension_event_index) {
- event = _ext_events->at(i);
- break;
- }
- }
- }
- if (event == NULL) {
- return JVMTI_ERROR_ILLEGAL_ARGUMENT;
- }
- JvmtiEventController::set_extension_event_callback(env, extension_event_index,
- callback);
- return JVMTI_ERROR_NONE;
- }
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiExtensions.hpp
- #ifndef SHARE_VM_PRIMS_JVMTIEXTENSIONS_HPP
- #define SHARE_VM_PRIMS_JVMTIEXTENSIONS_HPP
- #include "jvmtifiles/jvmti.h"
- #include "jvmtifiles/jvmtiEnv.hpp"
- #include "memory/allocation.hpp"
- class JvmtiExtensions : public AllStatic {
- private:
- static GrowableArray<jvmtiExtensionFunctionInfo*>* _ext_functions;
- static GrowableArray<jvmtiExtensionEventInfo*>* _ext_events;
- public:
- static void register_extensions();
- static jvmtiError get_functions(JvmtiEnv* env, jint* extension_count_ptr,
- jvmtiExtensionFunctionInfo** extensions);
- static jvmtiError get_events(JvmtiEnv* env, jint* extension_count_ptr,
- jvmtiExtensionEventInfo** extensions);
- static jvmtiError set_event_callback(JvmtiEnv* env, jint extension_event_index,
- jvmtiExtensionEvent callback);
- };
- #endif // SHARE_VM_PRIMS_JVMTIEXTENSIONS_HPP
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiGen.java
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import javax.xml.parsers.FactoryConfigurationError;
- import javax.xml.parsers.ParserConfigurationException;
- import org.xml.sax.SAXException;
- import org.xml.sax.SAXParseException;
- import org.w3c.dom.Document;
- import org.w3c.dom.DOMException;
- import javax.xml.transform.Transformer;
- import javax.xml.transform.TransformerException;
- import javax.xml.transform.TransformerFactory;
- import javax.xml.transform.TransformerConfigurationException;
- import javax.xml.transform.dom.DOMSource;
- import javax.xml.transform.stream.StreamSource;
- import javax.xml.transform.stream.StreamResult;
- import java.io.*;
- public class jvmtiGen
- {
- private static void showUsage() {
- System.err.println("usage:");
- System.err.println(" java jvmtiGen " +
- "-IN <input XML file name> " +
- "-XSL <XSL file> " +
- "-OUT <output file name> " +
- "[-PARAM <name> <expression> ...]");
- System.exit(0); // There is no returning from showUsage()
- }
- static Document document;
- public static void main (String argv [])
- {
- String inFileName=null;
- String xslFileName=null;
- String outFileName=null;
- java.util.Vector<String> params=new java.util.Vector<String>();
- for (int ii = 0; ii < argv.length; ii++) {
- if (argv[ii].equals("-IN")) {
- inFileName = argv[++ii];
- } else if (argv[ii].equals("-XSL")) {
- xslFileName = argv[++ii];
- } else if (argv[ii].equals("-OUT")) {
- outFileName = argv[++ii];
- } else if (argv[ii].equals("-PARAM")) {
- if (ii + 2 < argv.length) {
- String name = argv[++ii];
- params.addElement(name);
- String expression = argv[++ii];
- params.addElement(expression);
- } else {
- showUsage();
- }
- } else {
- showUsage();
- }
- }
- if (inFileName==null || xslFileName==null || outFileName==null){
- showUsage();
- }
- final String parserProperty =
- "javax.xml.transform.TransformerFactory";
- final String workaroundParser =
- "org.apache.xalan.processor.TransformerFactoryImpl";
- try {
- java.lang.Class cls = java.lang.Class.forName(workaroundParser);
- System.setProperty(parserProperty, workaroundParser);
- System.out.println("Info: jvmtiGen using " + parserProperty +
- " = " + workaroundParser);
- } catch (ClassNotFoundException cnfex) {
- }
- DocumentBuilderFactory factory =
- DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- factory.setValidating(true);
- factory.setXIncludeAware(true);
- try {
- File datafile = new File(inFileName);
- File stylesheet = new File(xslFileName);
- DocumentBuilder builder = factory.newDocumentBuilder();
- document = builder.parse(datafile);
- TransformerFactory tFactory =
- TransformerFactory.newInstance();
- StreamSource stylesource = new StreamSource(stylesheet);
- Transformer transformer = tFactory.newTransformer(stylesource);
- for (int ii = 0; ii < params.size(); ii += 2){
- transformer.setParameter((String) params.elementAt(ii),
- (String) params.elementAt(ii + 1));
- }
- DOMSource source = new DOMSource(document);
- PrintStream ps = new PrintStream( new FileOutputStream(outFileName));
- StreamResult result = new StreamResult(ps);
- transformer.transform(source, result);
- } catch (TransformerConfigurationException tce) {
- System.out.println ("\n** Transformer Factory error");
- System.out.println(" " + tce.getMessage() );
- Throwable x = tce;
- if (tce.getException() != null)
- x = tce.getException();
- x.printStackTrace();
- } catch (TransformerException te) {
- System.out.println ("\n** Transformation error");
- System.out.println(" " + te.getMessage() );
- Throwable x = te;
- if (te.getException() != null)
- x = te.getException();
- x.printStackTrace();
- } catch (SAXException sxe) {
- Exception x = sxe;
- if (sxe.getException() != null)
- x = sxe.getException();
- x.printStackTrace();
- } catch (ParserConfigurationException pce) {
- pce.printStackTrace();
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- } // main
- }
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiGetLoadedClasses.cpp
- #include "precompiled.hpp"
- #include "classfile/systemDictionary.hpp"
- #include "memory/universe.inline.hpp"
- #include "prims/jvmtiGetLoadedClasses.hpp"
- #include "runtime/thread.hpp"
- #if INCLUDE_ALL_GCS
- #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
- #endif
- class LoadedClassesClosure : public KlassClosure {
- private:
- Stack<jclass, mtInternal> _classStack;
- JvmtiEnv* _env;
- static void ensure_klass_alive(oop o) {
- #if INCLUDE_ALL_GCS
- if (UseG1GC && o != NULL) {
- G1SATBCardTableModRefBS::enqueue(o);
- }
- #endif
- }
- public:
- LoadedClassesClosure(JvmtiEnv* env) {
- _env = env;
- }
- void do_klass(Klass* k) {
- _classStack.push((jclass) _env->jni_reference(k->java_mirror()));
- ensure_klass_alive(k->java_mirror());
- }
- int extract(jclass* result_list) {
- int count = (int)_classStack.size();
- int i = count;
- while (!_classStack.is_empty()) {
- result_list[--i] = _classStack.pop();
- }
- return count;
- }
- int get_count() {
- return (int)_classStack.size();
- }
- };
- class JvmtiGetLoadedClassesClosure : public StackObj {
- private:
- jobject _initiatingLoader;
- int _count;
- Handle* _list;
- int _index;
- private:
- static JvmtiGetLoadedClassesClosure* get_this() {
- JvmtiGetLoadedClassesClosure* result = NULL;
- JavaThread* thread = JavaThread::current();
- result = thread->get_jvmti_get_loaded_classes_closure();
- return result;
- }
- static void set_this(JvmtiGetLoadedClassesClosure* that) {
- JavaThread* thread = JavaThread::current();
- thread->set_jvmti_get_loaded_classes_closure(that);
- }
- public:
- JvmtiGetLoadedClassesClosure() {
- JvmtiGetLoadedClassesClosure* that = get_this();
- assert(that == NULL, "JvmtiGetLoadedClassesClosure in use");
- _initiatingLoader = NULL;
- _count = 0;
- _list = NULL;
- _index = 0;
- set_this(this);
- }
- JvmtiGetLoadedClassesClosure(jobject initiatingLoader) {
- JvmtiGetLoadedClassesClosure* that = get_this();
- assert(that == NULL, "JvmtiGetLoadedClassesClosure in use");
- _initiatingLoader = initiatingLoader;
- _count = 0;
- _list = NULL;
- _index = 0;
- set_this(this);
- }
- ~JvmtiGetLoadedClassesClosure() {
- JvmtiGetLoadedClassesClosure* that = get_this();
- assert(that != NULL, "JvmtiGetLoadedClassesClosure not found");
- set_this(NULL);
- _initiatingLoader = NULL;
- _count = 0;
- if (_list != NULL) {
- FreeHeap(_list);
- _list = NULL;
- }
- _index = 0;
- }
- jobject get_initiatingLoader() {
- return _initiatingLoader;
- }
- int get_count() {
- return _count;
- }
- void set_count(int value) {
- _count = value;
- }
- Handle* get_list() {
- return _list;
- }
- void set_list(Handle* value) {
- _list = value;
- }
- int get_index() {
- return _index;
- }
- void set_index(int value) {
- _index = value;
- }
- Handle get_element(int index) {
- if ((_list != NULL) && (index < _count)) {
- return _list[index];
- } else {
- assert(false, "empty get_element");
- return Handle();
- }
- }
- void set_element(int index, Handle value) {
- if ((_list != NULL) && (index < _count)) {
- _list[index] = value;
- } else {
- assert(false, "bad set_element");
- }
- }
- bool available() {
- return (_list != NULL);
- }
- #ifdef ASSERT
- void check(int limit) {
- for (int i = 0; i < limit; i += 1) {
- assert(Universe::heap()->is_in(get_element(i)()), "check fails");
- }
- }
- #endif
- void allocate() {
- _list = NEW_C_HEAP_ARRAY(Handle, _count, mtInternal);
- assert(_list != NULL, "Out of memory");
- if (_list == NULL) {
- _count = 0;
- }
- }
- void extract(JvmtiEnv *env, jclass* result) {
- for (int index = 0; index < _count; index += 1) {
- result[index] = (jclass) env->jni_reference(get_element(index));
- }
- }
- static void increment_with_loader(Klass* k, ClassLoaderData* loader_data) {
- JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
- oop class_loader = loader_data->class_loader();
- if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
- for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
- that->set_count(that->get_count() + 1);
- }
- }
- }
- static void prim_array_increment_with_loader(Klass* array, ClassLoaderData* loader_data) {
- JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
- oop class_loader = loader_data->class_loader();
- if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
- that->set_count(that->get_count() + 1);
- }
- }
- static void add_with_loader(Klass* k, ClassLoaderData* loader_data) {
- JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
- if (that->available()) {
- oop class_loader = loader_data->class_loader();
- if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
- for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
- oop mirror = l->java_mirror();
- that->set_element(that->get_index(), mirror);
- that->set_index(that->get_index() + 1);
- }
- }
- }
- }
- static void increment_for_basic_type_arrays(Klass* k) {
- JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
- assert(that != NULL, "no JvmtiGetLoadedClassesClosure");
- for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
- that->set_count(that->get_count() + 1);
- }
- }
- static void add_for_basic_type_arrays(Klass* k) {
- JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
- assert(that != NULL, "no JvmtiGetLoadedClassesClosure");
- assert(that->available(), "no list");
- for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
- oop mirror = l->java_mirror();
- that->set_element(that->get_index(), mirror);
- that->set_index(that->get_index() + 1);
- }
- }
- };
- jvmtiError
- JvmtiGetLoadedClasses::getLoadedClasses(JvmtiEnv *env, jint* classCountPtr, jclass** classesPtr) {
- LoadedClassesClosure closure(env);
- {
- MutexLocker ma(MultiArray_lock);
- ClassLoaderDataGraph::loaded_classes_do(&closure);
- }
- jclass* result_list;
- jvmtiError error = env->Allocate(closure.get_count() * sizeof(jclass),
- (unsigned char**)&result_list);
- if (error == JVMTI_ERROR_NONE) {
- int count = closure.extract(result_list);
- }
- return error;
- }
- jvmtiError
- JvmtiGetLoadedClasses::getClassLoaderClasses(JvmtiEnv *env, jobject initiatingLoader,
- jint* classCountPtr, jclass** classesPtr) {
- JvmtiGetLoadedClassesClosure closure(initiatingLoader);
- {
- MutexLocker ma(MultiArray_lock);
- MutexLocker sd(SystemDictionary_lock);
- SystemDictionary::classes_do(&JvmtiGetLoadedClassesClosure::increment_with_loader);
- Universe::basic_type_classes_do(&JvmtiGetLoadedClassesClosure::increment_for_basic_type_arrays);
- closure.allocate();
- SystemDictionary::classes_do(&JvmtiGetLoadedClassesClosure::add_with_loader);
- Universe::basic_type_classes_do(&JvmtiGetLoadedClassesClosure::add_for_basic_type_arrays);
- }
- jclass* result_list;
- jvmtiError err = env->Allocate(closure.get_count() * sizeof(jclass),
- (unsigned char**)&result_list);
- if (err != JVMTI_ERROR_NONE) {
- return err;
- }
- closure.extract(env, result_list);
- return JVMTI_ERROR_NONE;
- }
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiGetLoadedClasses.hpp
- #ifndef SHARE_VM_PRIMS_JVMTIGETLOADEDCLASSES_HPP
- #define SHARE_VM_PRIMS_JVMTIGETLOADEDCLASSES_HPP
- #include "jvmtifiles/jvmtiEnv.hpp"
- class JvmtiGetLoadedClasses : AllStatic {
- public:
- static jvmtiError getLoadedClasses(JvmtiEnv *env, jint* classCountPtr, jclass** classesPtr);
- static jvmtiError getClassLoaderClasses(JvmtiEnv *env, jobject initiatingLoader,
- jint* classCountPtr, jclass** classesPtr);
- };
- #endif // SHARE_VM_PRIMS_JVMTIGETLOADEDCLASSES_HPP
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiImpl.cpp
- #include "precompiled.hpp"
- #include "classfile/systemDictionary.hpp"
- #include "interpreter/interpreter.hpp"
- #include "interpreter/oopMapCache.hpp"
- #include "jvmtifiles/jvmtiEnv.hpp"
- #include "memory/resourceArea.hpp"
- #include "oops/instanceKlass.hpp"
- #include "prims/jvmtiAgentThread.hpp"
- #include "prims/jvmtiEventController.inline.hpp"
- #include "prims/jvmtiImpl.hpp"
- #include "prims/jvmtiRedefineClasses.hpp"
- #include "runtime/atomic.hpp"
- #include "runtime/deoptimization.hpp"
- #include "runtime/handles.hpp"
- #include "runtime/handles.inline.hpp"
- #include "runtime/interfaceSupport.hpp"
- #include "runtime/javaCalls.hpp"
- #include "runtime/os.hpp"
- #include "runtime/serviceThread.hpp"
- #include "runtime/signature.hpp"
- #include "runtime/thread.inline.hpp"
- #include "runtime/vframe.hpp"
- #include "runtime/vframe_hp.hpp"
- #include "runtime/vm_operations.hpp"
- #include "utilities/exceptions.hpp"
- JvmtiAgentThread::JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg)
- : JavaThread(start_function_wrapper) {
- _env = env;
- _start_fn = start_fn;
- _start_arg = start_arg;
- }
- void
- JvmtiAgentThread::start_function_wrapper(JavaThread *thread, TRAPS) {
- assert(thread->is_Java_thread(), "debugger thread should be a Java Thread");
- assert(thread == JavaThread::current(), "sanity check");
- JvmtiAgentThread *dthread = (JvmtiAgentThread *)thread;
- dthread->call_start_function();
- }
- void
- JvmtiAgentThread::call_start_function() {
- ThreadToNativeFromVM transition(this);
- _start_fn(_env->jvmti_external(), jni_environment(), (void*)_start_arg);
- }
- void GrowableCache::recache() {
- int len = _elements->length();
- FREE_C_HEAP_ARRAY(address, _cache, mtInternal);
- _cache = NEW_C_HEAP_ARRAY(address,len+1, mtInternal);
- for (int i=0; i<len; i++) {
- _cache[i] = _elements->at(i)->getCacheValue();
- if (_cache[i] == NULL) {
- assert(false, "cannot recache NULL elements");
- remove(i);
- return;
- }
- }
- _cache[len] = NULL;
- _listener_fun(_this_obj,_cache);
- }
- bool GrowableCache::equals(void* v, GrowableElement *e2) {
- GrowableElement *e1 = (GrowableElement *) v;
- assert(e1 != NULL, "e1 != NULL");
- assert(e2 != NULL, "e2 != NULL");
- return e1->equals(e2);
- }
- GrowableCache::GrowableCache() {
- _this_obj = NULL;
- _listener_fun = NULL;
- _elements = NULL;
- _cache = NULL;
- }
- GrowableCache::~GrowableCache() {
- clear();
- delete _elements;
- FREE_C_HEAP_ARRAY(address, _cache, mtInternal);
- }
- void GrowableCache::initialize(void *this_obj, void listener_fun(void *, address*) ) {
- _this_obj = this_obj;
- _listener_fun = listener_fun;
- _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<GrowableElement*>(5,true);
- recache();
- }
- int GrowableCache::length() {
- return _elements->length();
- }
- GrowableElement* GrowableCache::at(int index) {
- GrowableElement *e = (GrowableElement *) _elements->at(index);
- assert(e != NULL, "e != NULL");
- return e;
- }
- int GrowableCache::find(GrowableElement* e) {
- return _elements->find(e, GrowableCache::equals);
- }
- void GrowableCache::append(GrowableElement* e) {
- GrowableElement *new_e = e->clone();
- _elements->append(new_e);
- recache();
- }
- void GrowableCache::insert(GrowableElement* e) {
- GrowableElement *new_e = e->clone();
- _elements->append(new_e);
- int n = length()-2;
- for (int i=n; i>=0; i--) {
- GrowableElement *e1 = _elements->at(i);
- GrowableElement *e2 = _elements->at(i+1);
- if (e2->lessThan(e1)) {
- _elements->at_put(i+1, e1);
- _elements->at_put(i, e2);
- }
- }
- recache();
- }
- void GrowableCache::remove (int index) {
- GrowableElement *e = _elements->at(index);
- assert(e != NULL, "e != NULL");
- _elements->remove(e);
- delete e;
- recache();
- }
- void GrowableCache::clear() {
- int len = _elements->length();
- for (int i=0; i<len; i++) {
- delete _elements->at(i);
- }
- _elements->clear();
- recache();
- }
- void GrowableCache::oops_do(OopClosure* f) {
- int len = _elements->length();
- for (int i=0; i<len; i++) {
- GrowableElement *e = _elements->at(i);
- e->oops_do(f);
- }
- }
- void GrowableCache::metadata_do(void f(Metadata*)) {
- int len = _elements->length();
- for (int i=0; i<len; i++) {
- GrowableElement *e = _elements->at(i);
- e->metadata_do(f);
- }
- }
- void GrowableCache::gc_epilogue() {
- int len = _elements->length();
- for (int i=0; i<len; i++) {
- _cache[i] = _elements->at(i)->getCacheValue();
- }
- }
- JvmtiBreakpoint::JvmtiBreakpoint() {
- _method = NULL;
- _bci = 0;
- _class_holder = NULL;
- }
- JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location) {
- _method = m_method;
- _class_holder = _method->method_holder()->klass_holder();
- #ifdef CHECK_UNHANDLED_OOPS
- Thread::current()->allow_unhandled_oop(&_class_holder);
- #endif // CHECK_UNHANDLED_OOPS
- assert(_method != NULL, "_method != NULL");
- _bci = (int) location;
- assert(_bci >= 0, "_bci >= 0");
- }
- void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) {
- _method = bp._method;
- _bci = bp._bci;
- _class_holder = bp._class_holder;
- }
- bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) {
- Unimplemented();
- return false;
- }
- bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) {
- return _method == bp._method
- && _bci == bp._bci;
- }
- bool JvmtiBreakpoint::is_valid() {
- return _method != NULL &&
- _bci >= 0;
- }
- address JvmtiBreakpoint::getBcp() {
- return _method->bcp_from(_bci);
- }
- void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
- ((Method*)_method->*meth_act)(_bci);
- Thread *thread = Thread::current();
- instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder());
- Symbol* m_name = _method->name();
- Symbol* m_signature = _method->signature();
- for (InstanceKlass* pv_node = ikh->previous_versions();
- pv_node != NULL;
- pv_node = pv_node->previous_versions()) {
- Array<Method*>* methods = pv_node->methods();
- for (int i = methods->length() - 1; i >= 0; i--) {
- Method* method = methods->at(i);
- if (method->is_running_emcp() &&
- method->name() == m_name &&
- method->signature() == m_signature) {
- RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",
- meth_act == &Method::set_breakpoint ? "sett" : "clear",
- method->name()->as_C_string(),
- method->signature()->as_C_string()));
- (method->*meth_act)(_bci);
- break;
- }
- }
- }
- }
- void JvmtiBreakpoint::set() {
- each_method_version_do(&Method::set_breakpoint);
- }
- void JvmtiBreakpoint::clear() {
- each_method_version_do(&Method::clear_breakpoint);
- }
- void JvmtiBreakpoint::print() {
- #ifndef PRODUCT
- const char *class_name = (_method == NULL) ? "NULL" : _method->klass_name()->as_C_string();
- const char *method_name = (_method == NULL) ? "NULL" : _method->name()->as_C_string();
- tty->print("Breakpoint(%s,%s,%d,%p)",class_name, method_name, _bci, getBcp());
- #endif
- }
- void VM_ChangeBreakpoints::doit() {
- switch (_operation) {
- case SET_BREAKPOINT:
- _breakpoints->set_at_safepoint(*_bp);
- break;
- case CLEAR_BREAKPOINT:
- _breakpoints->clear_at_safepoint(*_bp);
- break;
- default:
- assert(false, "Unknown operation");
- }
- }
- void VM_ChangeBreakpoints::oops_do(OopClosure* f) {
- if (_bp != NULL) {
- _bp->oops_do(f);
- }
- }
- void VM_ChangeBreakpoints::metadata_do(void f(Metadata*)) {
- if (_bp != NULL) {
- _bp->metadata_do(f);
- }
- }
- JvmtiBreakpoints::JvmtiBreakpoints(void listener_fun(void *,address *)) {
- _bps.initialize(this,listener_fun);
- }
- JvmtiBreakpoints:: ~JvmtiBreakpoints() {}
- void JvmtiBreakpoints::oops_do(OopClosure* f) {
- _bps.oops_do(f);
- }
- void JvmtiBreakpoints::metadata_do(void f(Metadata*)) {
- _bps.metadata_do(f);
- }
- void JvmtiBreakpoints::gc_epilogue() {
- _bps.gc_epilogue();
- }
- void JvmtiBreakpoints::print() {
- #ifndef PRODUCT
- ResourceMark rm;
- int n = _bps.length();
- for (int i=0; i<n; i++) {
- JvmtiBreakpoint& bp = _bps.at(i);
- tty->print("%d: ", i);
- bp.print();
- tty->cr();
- }
- #endif
- }
- void JvmtiBreakpoints::set_at_safepoint(JvmtiBreakpoint& bp) {
- assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
- int i = _bps.find(bp);
- if (i == -1) {
- _bps.append(bp);
- bp.set();
- }
- }
- void JvmtiBreakpoints::clear_at_safepoint(JvmtiBreakpoint& bp) {
- assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
- int i = _bps.find(bp);
- if (i != -1) {
- _bps.remove(i);
- bp.clear();
- }
- }
- int JvmtiBreakpoints::length() { return _bps.length(); }
- int JvmtiBreakpoints::set(JvmtiBreakpoint& bp) {
- if ( _bps.find(bp) != -1) {
- return JVMTI_ERROR_DUPLICATE;
- }
- VM_ChangeBreakpoints set_breakpoint(VM_ChangeBreakpoints::SET_BREAKPOINT, &bp);
- VMThread::execute(&set_breakpoint);
- return JVMTI_ERROR_NONE;
- }
- int JvmtiBreakpoints::clear(JvmtiBreakpoint& bp) {
- if ( _bps.find(bp) == -1) {
- return JVMTI_ERROR_NOT_FOUND;
- }
- VM_ChangeBreakpoints clear_breakpoint(VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp);
- VMThread::execute(&clear_breakpoint);
- return JVMTI_ERROR_NONE;
- }
- void JvmtiBreakpoints::clearall_in_class_at_safepoint(Klass* klass) {
- bool changed = true;
- while (changed) {
- int len = _bps.length();
- changed = false;
- for (int i = 0; i < len; i++) {
- JvmtiBreakpoint& bp = _bps.at(i);
- if (bp.method()->method_holder() == klass) {
- bp.clear();
- _bps.remove(i);
- changed = true;
- break;
- }
- }
- }
- }
- JvmtiBreakpoints *JvmtiCurrentBreakpoints::_jvmti_breakpoints = NULL;
- address * JvmtiCurrentBreakpoints::_breakpoint_list = NULL;
- JvmtiBreakpoints& JvmtiCurrentBreakpoints::get_jvmti_breakpoints() {
- if (_jvmti_breakpoints != NULL) return (*_jvmti_breakpoints);
- _jvmti_breakpoints = new JvmtiBreakpoints(listener_fun);
- assert(_jvmti_breakpoints != NULL, "_jvmti_breakpoints != NULL");
- return (*_jvmti_breakpoints);
- }
- void JvmtiCurrentBreakpoints::listener_fun(void *this_obj, address *cache) {
- JvmtiBreakpoints *this_jvmti = (JvmtiBreakpoints *) this_obj;
- assert(this_jvmti != NULL, "this_jvmti != NULL");
- debug_only(int n = this_jvmti->length(););
- assert(cache[n] == NULL, "cache must be NULL terminated");
- set_breakpoint_list(cache);
- }
- void JvmtiCurrentBreakpoints::oops_do(OopClosure* f) {
- if (_jvmti_breakpoints != NULL) {
- _jvmti_breakpoints->oops_do(f);
- }
- }
- void JvmtiCurrentBreakpoints::metadata_do(void f(Metadata*)) {
- if (_jvmti_breakpoints != NULL) {
- _jvmti_breakpoints->metadata_do(f);
- }
- }
- void JvmtiCurrentBreakpoints::gc_epilogue() {
- if (_jvmti_breakpoints != NULL) {
- _jvmti_breakpoints->gc_epilogue();
- }
- }
- VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type)
- : _thread(thread)
- , _calling_thread(NULL)
- , _depth(depth)
- , _index(index)
- , _type(type)
- , _set(false)
- , _jvf(NULL)
- , _result(JVMTI_ERROR_NONE)
- {
- }
- VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type, jvalue value)
- : _thread(thread)
- , _calling_thread(NULL)
- , _depth(depth)
- , _index(index)
- , _type(type)
- , _value(value)
- , _set(true)
- , _jvf(NULL)
- , _result(JVMTI_ERROR_NONE)
- {
- }
- VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index)
- : _thread(thread)
- , _calling_thread(calling_thread)
- , _depth(depth)
- , _index(index)
- , _type(T_OBJECT)
- , _set(false)
- , _jvf(NULL)
- , _result(JVMTI_ERROR_NONE)
- {
- }
- vframe *VM_GetOrSetLocal::get_vframe() {
- if (!_thread->has_last_Java_frame()) {
- return NULL;
- }
- RegisterMap reg_map(_thread);
- vframe *vf = _thread->last_java_vframe(®_map);
- int d = 0;
- while ((vf != NULL) && (d < _depth)) {
- vf = vf->java_sender();
- d++;
- }
- return vf;
- }
- javaVFrame *VM_GetOrSetLocal::get_java_vframe() {
- vframe* vf = get_vframe();
- if (vf == NULL) {
- _result = JVMTI_ERROR_NO_MORE_FRAMES;
- return NULL;
- }
- javaVFrame *jvf = (javaVFrame*)vf;
- if (!vf->is_java_frame()) {
- _result = JVMTI_ERROR_OPAQUE_FRAME;
- return NULL;
- }
- return jvf;
- }
- bool VM_GetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) {
- assert(ty_sign != NULL, "type signature must not be NULL");
- assert(thread != NULL, "thread must not be NULL");
- assert(klass != NULL, "klass must not be NULL");
- int len = (int) strlen(ty_sign);
- if (ty_sign[0] == 'L' && ty_sign[len-1] == ';') { // Need pure class/interface name
- ty_sign++;
- len -= 2;
- }
- TempNewSymbol ty_sym = SymbolTable::new_symbol(ty_sign, len, thread);
- if (klass->name() == ty_sym) {
- return true;
- }
- int super_depth = klass->super_depth();
- int idx;
- for (idx = 0; idx < super_depth; idx++) {
- if (klass->primary_super_of_depth(idx)->name() == ty_sym) {
- return true;
- }
- }
- Array<Klass*>* sec_supers = klass->secondary_supers();
- for (idx = 0; idx < sec_supers->length(); idx++) {
- if (((Klass*) sec_supers->at(idx))->name() == ty_sym) {
- return true;
- }
- }
- return false;
- }
- bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) {
- Method* method_oop = jvf->method();
- if (!method_oop->has_localvariable_table()) {
- jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0;
- if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) {
- _result = JVMTI_ERROR_INVALID_SLOT;
- return false;
- }
- return true;
- }
- jint num_entries = method_oop->localvariable_table_length();
- if (num_entries == 0) {
- _result = JVMTI_ERROR_INVALID_SLOT;
- return false; // There are no slots
- }
- int signature_idx = -1;
- int vf_bci = jvf->bci();
- LocalVariableTableElement* table = method_oop->localvariable_table_start();
- for (int i = 0; i < num_entries; i++) {
- int start_bci = table[i].start_bci;
- int end_bci = start_bci + table[i].length;
- if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) {
- signature_idx = (int) table[i].descriptor_cp_index;
- break;
- }
- }
- if (signature_idx == -1) {
- _result = JVMTI_ERROR_INVALID_SLOT;
- return false; // Incorrect slot index
- }
- Symbol* sign_sym = method_oop->constants()->symbol_at(signature_idx);
- const char* signature = (const char *) sign_sym->as_utf8();
- BasicType slot_type = char2type(signature[0]);
- switch (slot_type) {
- case T_BYTE:
- case T_SHORT:
- case T_CHAR:
- case T_BOOLEAN:
- slot_type = T_INT;
- break;
- case T_ARRAY:
- slot_type = T_OBJECT;
- break;
- };
- if (_type != slot_type) {
- _result = JVMTI_ERROR_TYPE_MISMATCH;
- return false;
- }
- jobject jobj = _value.l;
- if (_set && slot_type == T_OBJECT && jobj != NULL) { // NULL reference is allowed
- JavaThread* cur_thread = JavaThread::current();
- HandleMark hm(cur_thread);
- Handle obj = Handle(cur_thread, JNIHandles::resolve_external_guard(jobj));
- NULL_CHECK(obj, (_result = JVMTI_ERROR_INVALID_OBJECT, false));
- KlassHandle ob_kh = KlassHandle(cur_thread, obj->klass());
- NULL_CHECK(ob_kh, (_result = JVMTI_ERROR_INVALID_OBJECT, false));
- if (!is_assignable(signature, ob_kh(), cur_thread)) {
- _result = JVMTI_ERROR_TYPE_MISMATCH;
- return false;
- }
- }
- return true;
- }
- static bool can_be_deoptimized(vframe* vf) {
- return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized());
- }
- bool VM_GetOrSetLocal::doit_prologue() {
- _jvf = get_java_vframe();
- NULL_CHECK(_jvf, false);
- if (_jvf->method()->is_native()) {
- if (getting_receiver() && !_jvf->method()->is_static()) {
- return true;
- } else {
- _result = JVMTI_ERROR_OPAQUE_FRAME;
- return false;
- }
- }
- if (!check_slot_type(_jvf)) {
- return false;
- }
- return true;
- }
- void VM_GetOrSetLocal::doit() {
- InterpreterOopMap oop_mask;
- _jvf->method()->mask_for(_jvf->bci(), &oop_mask);
- if (oop_mask.is_dead(_index)) {
- _result = JVMTI_ERROR_INVALID_SLOT;
- return;
- }
- if (_set) {
- if (can_be_deoptimized(_jvf)) {
- Deoptimization::deoptimize_frame(_jvf->thread(), _jvf->fr().id());
- if (_type == T_OBJECT) {
- _value.l = (jobject) (JNIHandles::resolve_external_guard(_value.l));
- }
- _jvf = get_java_vframe();
- ((compiledVFrame*)_jvf)->update_local(_type, _index, _value);
- return;
- }
- StackValueCollection *locals = _jvf->locals();
- HandleMark hm;
- switch (_type) {
- case T_INT: locals->set_int_at (_index, _value.i); break;
- case T_LONG: locals->set_long_at (_index, _value.j); break;
- case T_FLOAT: locals->set_float_at (_index, _value.f); break;
- case T_DOUBLE: locals->set_double_at(_index, _value.d); break;
- case T_OBJECT: {
- Handle ob_h(JNIHandles::resolve_external_guard(_value.l));
- locals->set_obj_at (_index, ob_h);
- break;
- }
- default: ShouldNotReachHere();
- }
- _jvf->set_locals(locals);
- } else {
- if (_jvf->method()->is_native() && _jvf->is_compiled_frame()) {
- assert(getting_receiver(), "Can only get here when getting receiver");
- oop receiver = _jvf->fr().get_native_receiver();
- _value.l = JNIHandles::make_local(_calling_thread, receiver);
- } else {
- StackValueCollection *locals = _jvf->locals();
- if (locals->at(_index)->type() == T_CONFLICT) {
- memset(&_value, 0, sizeof(_value));
- _value.l = NULL;
- return;
- }
- switch (_type) {
- case T_INT: _value.i = locals->int_at (_index); break;
- case T_LONG: _value.j = locals->long_at (_index); break;
- case T_FLOAT: _value.f = locals->float_at (_index); break;
- case T_DOUBLE: _value.d = locals->double_at(_index); break;
- case T_OBJECT: {
- oop obj = locals->obj_at(_index)();
- _value.l = JNIHandles::make_local(_calling_thread, obj);
- break;
- }
- default: ShouldNotReachHere();
- }
- }
- }
- }
- bool VM_GetOrSetLocal::allow_nested_vm_operations() const {
- return true; // May need to deoptimize
- }
- VM_GetReceiver::VM_GetReceiver(
- JavaThread* thread, JavaThread* caller_thread, jint depth)
- : VM_GetOrSetLocal(thread, caller_thread, depth, 0) {}
- bool JvmtiSuspendControl::suspend(JavaThread *java_thread) {
- java_thread->java_suspend();
- if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) {
- return false;
- }
- return true;
- }
- bool JvmtiSuspendControl::resume(JavaThread *java_thread) {
- assert(java_thread->is_being_ext_suspended(), "thread should be suspended");
- {
- MutexLocker ml(Threads_lock);
- java_thread->java_resume();
- }
- return true;
- }
- void JvmtiSuspendControl::print() {
- #ifndef PRODUCT
- MutexLocker mu(Threads_lock);
- ResourceMark rm;
- tty->print("Suspended Threads: [");
- for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
- #ifdef JVMTI_TRACE
- const char *name = JvmtiTrace::safe_get_thread_name(thread);
- #else
- const char *name = "";
- #endif /*JVMTI_TRACE */
- tty->print("%s(%c ", name, thread->is_being_ext_suspended() ? 'S' : '_');
- if (!thread->has_last_Java_frame()) {
- tty->print("no stack");
- }
- tty->print(") ");
- }
- tty->print_cr("]");
- #endif
- }
- JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event(
- nmethod* nm) {
- JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD);
- event._event_data.compiled_method_load = nm;
- nmethodLocker::lock_nmethod(nm);
- return event;
- }
- JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_unload_event(
- nmethod* nm, jmethodID id, const void* code) {
- JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_UNLOAD);
- event._event_data.compiled_method_unload.nm = nm;
- event._event_data.compiled_method_unload.method_id = id;
- event._event_data.compiled_method_unload.code_begin = code;
- nmethodLocker::lock_nmethod(nm, true /* zombie_ok */);
- return event;
- }
- JvmtiDeferredEvent JvmtiDeferredEvent::dynamic_code_generated_event(
- const char* name, const void* code_begin, const void* code_end) {
- JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_DYNAMIC_CODE_GENERATED);
- event._event_data.dynamic_code_generated.name = os::strdup(name);
- event._event_data.dynamic_code_generated.code_begin = code_begin;
- event._event_data.dynamic_code_generated.code_end = code_end;
- return event;
- }
- void JvmtiDeferredEvent::post() {
- assert(ServiceThread::is_service_thread(Thread::current()),
- "Service thread must post enqueued events");
- switch(_type) {
- case TYPE_COMPILED_METHOD_LOAD: {
- nmethod* nm = _event_data.compiled_method_load;
- JvmtiExport::post_compiled_method_load(nm);
- nmethodLocker::unlock_nmethod(nm);
- break;
- }
- case TYPE_COMPILED_METHOD_UNLOAD: {
- nmethod* nm = _event_data.compiled_method_unload.nm;
- JvmtiExport::post_compiled_method_unload(
- _event_data.compiled_method_unload.method_id,
- _event_data.compiled_method_unload.code_begin);
- nmethodLocker::unlock_nmethod(nm);
- break;
- }
- case TYPE_DYNAMIC_CODE_GENERATED: {
- JvmtiExport::post_dynamic_code_generated_internal(
- (_event_data.dynamic_code_generated.name == NULL)
- ? "unknown_code" : _event_data.dynamic_code_generated.name,
- _event_data.dynamic_code_generated.code_begin,
- _event_data.dynamic_code_generated.code_end);
- if (_event_data.dynamic_code_generated.name != NULL) {
- os::free((void *)_event_data.dynamic_code_generated.name);
- }
- break;
- }
- default:
- ShouldNotReachHere();
- }
- }
- JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_tail = NULL;
- JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_head = NULL;
- volatile JvmtiDeferredEventQueue::QueueNode*
- JvmtiDeferredEventQueue::_pending_list = NULL;
- bool JvmtiDeferredEventQueue::has_events() {
- assert(Service_lock->owned_by_self(), "Must own Service_lock");
- return _queue_head != NULL || _pending_list != NULL;
- }
- void JvmtiDeferredEventQueue::enqueue(const JvmtiDeferredEvent& event) {
- assert(Service_lock->owned_by_self(), "Must own Service_lock");
- process_pending_events();
- QueueNode* node = new QueueNode(event);
- if (_queue_tail == NULL) {
- _queue_tail = _queue_head = node;
- } else {
- assert(_queue_tail->next() == NULL, "Must be the last element in the list");
- _queue_tail->set_next(node);
- _queue_tail = node;
- }
- Service_lock->notify_all();
- assert((_queue_head == NULL) == (_queue_tail == NULL),
- "Inconsistent queue markers");
- }
- JvmtiDeferredEvent JvmtiDeferredEventQueue::dequeue() {
- assert(Service_lock->owned_by_self(), "Must own Service_lock");
- process_pending_events();
- assert(_queue_head != NULL, "Nothing to dequeue");
- if (_queue_head == NULL) {
- return JvmtiDeferredEvent();
- }
- QueueNode* node = _queue_head;
- _queue_head = _queue_head->next();
- if (_queue_head == NULL) {
- _queue_tail = NULL;
- }
- assert((_queue_head == NULL) == (_queue_tail == NULL),
- "Inconsistent queue markers");
- JvmtiDeferredEvent event = node->event();
- delete node;
- return event;
- }
- void JvmtiDeferredEventQueue::add_pending_event(
- const JvmtiDeferredEvent& event) {
- QueueNode* node = new QueueNode(event);
- bool success = false;
- QueueNode* prev_value = (QueueNode*)_pending_list;
- do {
- node->set_next(prev_value);
- prev_value = (QueueNode*)Atomic::cmpxchg_ptr(
- (void*)node, (volatile void*)&_pending_list, (void*)node->next());
- } while (prev_value != node->next());
- }
- void JvmtiDeferredEventQueue::process_pending_events() {
- assert(Service_lock->owned_by_self(), "Must own Service_lock");
- if (_pending_list != NULL) {
- QueueNode* head =
- (QueueNode*)Atomic::xchg_ptr(NULL, (volatile void*)&_pending_list);
- assert((_queue_head == NULL) == (_queue_tail == NULL),
- "Inconsistent queue markers");
- if (head != NULL) {
- QueueNode* new_tail = head;
- QueueNode* new_head = NULL;
- QueueNode* prev = new_tail;
- QueueNode* node = new_tail->next();
- new_tail->set_next(NULL);
- while (node != NULL) {
- QueueNode* next = node->next();
- node->set_next(prev);
- prev = node;
- node = next;
- }
- new_head = prev;
- if (_queue_tail != NULL) {
- _queue_tail->set_next(new_head);
- } else { // _queue_head == NULL
- _queue_head = new_head;
- }
- _queue_tail = new_tail;
- }
- }
- }
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiImpl.hpp
- #ifndef SHARE_VM_PRIMS_JVMTIIMPL_HPP
- #define SHARE_VM_PRIMS_JVMTIIMPL_HPP
- #include "classfile/systemDictionary.hpp"
- #include "jvmtifiles/jvmti.h"
- #include "oops/objArrayOop.hpp"
- #include "prims/jvmtiEnvThreadState.hpp"
- #include "prims/jvmtiEventController.hpp"
- #include "prims/jvmtiTrace.hpp"
- #include "prims/jvmtiUtil.hpp"
- #include "runtime/stackValueCollection.hpp"
- #include "runtime/vm_operations.hpp"
- class JvmtiBreakpoint;
- class JvmtiBreakpoints;
- class GrowableElement : public CHeapObj<mtInternal> {
- public:
- virtual ~GrowableElement() {}
- virtual address getCacheValue() =0;
- virtual bool equals(GrowableElement* e) =0;
- virtual bool lessThan(GrowableElement *e)=0;
- virtual GrowableElement *clone() =0;
- virtual void oops_do(OopClosure* f) =0;
- virtual void metadata_do(void f(Metadata*)) =0;
- };
- class GrowableCache VALUE_OBJ_CLASS_SPEC {
- private:
- void *_this_obj;
- GrowableArray<GrowableElement *> *_elements;
- address *_cache;
- void (*_listener_fun)(void *, address*);
- static bool equals(void *, GrowableElement *);
- void recache();
- public:
- GrowableCache();
- ~GrowableCache();
- void initialize(void *this_obj, void listener_fun(void *, address*) );
- int length();
- GrowableElement* at(int index);
- int find(GrowableElement* e);
- void append(GrowableElement* e);
- void insert(GrowableElement* e);
- void remove (int index);
- void clear();
- void oops_do(OopClosure* f);
- void metadata_do(void f(Metadata*));
- void gc_epilogue();
- };
- class JvmtiBreakpointCache : public CHeapObj<mtInternal> {
- private:
- GrowableCache _cache;
- public:
- JvmtiBreakpointCache() {}
- ~JvmtiBreakpointCache() {}
- void initialize(void *this_obj, void listener_fun(void *, address*) ) {
- _cache.initialize(this_obj,listener_fun);
- }
- int length() { return _cache.length(); }
- JvmtiBreakpoint& at(int index) { return (JvmtiBreakpoint&) *(_cache.at(index)); }
- int find(JvmtiBreakpoint& e) { return _cache.find((GrowableElement *) &e); }
- void append(JvmtiBreakpoint& e) { _cache.append((GrowableElement *) &e); }
- void remove (int index) { _cache.remove(index); }
- void clear() { _cache.clear(); }
- void oops_do(OopClosure* f) { _cache.oops_do(f); }
- void metadata_do(void f(Metadata*)) { _cache.metadata_do(f); }
- void gc_epilogue() { _cache.gc_epilogue(); }
- };
- typedef void (Method::*method_action)(int _bci);
- class JvmtiBreakpoint : public GrowableElement {
- private:
- Method* _method;
- int _bci;
- Bytecodes::Code _orig_bytecode;
- oop _class_holder; // keeps _method memory from being deallocated
- public:
- JvmtiBreakpoint();
- JvmtiBreakpoint(Method* m_method, jlocation location);
- bool equals(JvmtiBreakpoint& bp);
- bool lessThan(JvmtiBreakpoint &bp);
- void copy(JvmtiBreakpoint& bp);
- bool is_valid();
- address getBcp();
- void each_method_version_do(method_action meth_act);
- void set();
- void clear();
- void print();
- Method* method() { return _method; }
- address getCacheValue() { return getBcp(); }
- bool lessThan(GrowableElement* e) { Unimplemented(); return false; }
- bool equals(GrowableElement* e) { return equals((JvmtiBreakpoint&) *e); }
- void oops_do(OopClosure* f) {
- f->do_oop(&_class_holder);
- }
- void metadata_do(void f(Metadata*)) {
- f(_method);
- }
- GrowableElement *clone() {
- JvmtiBreakpoint *bp = new JvmtiBreakpoint();
- bp->copy(*this);
- return bp;
- }
- };
- class JvmtiBreakpoints : public CHeapObj<mtInternal> {
- private:
- JvmtiBreakpointCache _bps;
- friend class VM_ChangeBreakpoints;
- void set_at_safepoint(JvmtiBreakpoint& bp);
- void clear_at_safepoint(JvmtiBreakpoint& bp);
- static void do_element(GrowableElement *e);
- public:
- JvmtiBreakpoints(void listener_fun(void *, address *));
- ~JvmtiBreakpoints();
- int length();
- void oops_do(OopClosure* f);
- void metadata_do(void f(Metadata*));
- void print();
- int set(JvmtiBreakpoint& bp);
- int clear(JvmtiBreakpoint& bp);
- void clearall_in_class_at_safepoint(Klass* klass);
- void gc_epilogue();
- };
- class JvmtiCurrentBreakpoints : public AllStatic {
- private:
- static JvmtiBreakpoints *_jvmti_breakpoints;
- static address *_breakpoint_list;
- static inline void set_breakpoint_list(address *breakpoint_list) { _breakpoint_list = breakpoint_list; }
- static inline address *get_breakpoint_list() { return _breakpoint_list; }
- static void listener_fun(void *this_obj, address *cache);
- public:
- static void initialize();
- static void destroy();
- static JvmtiBreakpoints& get_jvmti_breakpoints();
- static inline bool is_breakpoint(address bcp);
- static void oops_do(OopClosure* f);
- static void metadata_do(void f(Metadata*)) NOT_JVMTI_RETURN;
- static void gc_epilogue();
- };
- bool JvmtiCurrentBreakpoints::is_breakpoint(address bcp) {
- address *bps = get_breakpoint_list();
- if (bps == NULL) return false;
- for ( ; (*bps) != NULL; bps++) {
- if ((*bps) == bcp) return true;
- }
- return false;
- }
- class VM_ChangeBreakpoints : public VM_Operation {
- private:
- JvmtiBreakpoints* _breakpoints;
- int _operation;
- JvmtiBreakpoint* _bp;
- public:
- enum { SET_BREAKPOINT=0, CLEAR_BREAKPOINT=1 };
- VM_ChangeBreakpoints(int operation, JvmtiBreakpoint *bp) {
- JvmtiBreakpoints& current_bps = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
- _breakpoints = ¤t_bps;
- _bp = bp;
- _operation = operation;
- assert(bp != NULL, "bp != NULL");
- }
- VMOp_Type type() const { return VMOp_ChangeBreakpoints; }
- void doit();
- void oops_do(OopClosure* f);
- void metadata_do(void f(Metadata*));
- };
- class VM_GetOrSetLocal : public VM_Operation {
- protected:
- JavaThread* _thread;
- JavaThread* _calling_thread;
- jint _depth;
- jint _index;
- BasicType _type;
- jvalue _value;
- javaVFrame* _jvf;
- bool _set;
- virtual bool getting_receiver() const { return false; }
- jvmtiError _result;
- vframe* get_vframe();
- javaVFrame* get_java_vframe();
- bool check_slot_type(javaVFrame* vf);
- public:
- VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type);
- VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, jvalue value);
- VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth,
- int index);
- VMOp_Type type() const { return VMOp_GetOrSetLocal; }
- jvalue value() { return _value; }
- jvmtiError result() { return _result; }
- bool doit_prologue();
- void doit();
- bool allow_nested_vm_operations() const;
- const char* name() const { return "get/set locals"; }
- static bool is_assignable(const char* ty_sign, Klass* klass, Thread* thread);
- };
- class VM_GetReceiver : public VM_GetOrSetLocal {
- protected:
- virtual bool getting_receiver() const { return true; }
- public:
- VM_GetReceiver(JavaThread* thread, JavaThread* calling_thread, jint depth);
- const char* name() const { return "get receiver"; }
- };
- class JvmtiSuspendControl : public AllStatic {
- public:
- static bool suspend(JavaThread *java_thread);
- static bool resume(JavaThread *java_thread);
- static void print();
- };
- class JvmtiDeferredEvent VALUE_OBJ_CLASS_SPEC {
- friend class JvmtiDeferredEventQueue;
- private:
- typedef enum {
- TYPE_NONE,
- TYPE_COMPILED_METHOD_LOAD,
- TYPE_COMPILED_METHOD_UNLOAD,
- TYPE_DYNAMIC_CODE_GENERATED
- } Type;
- Type _type;
- union {
- nmethod* compiled_method_load;
- struct {
- nmethod* nm;
- jmethodID method_id;
- const void* code_begin;
- } compiled_method_unload;
- struct {
- const char* name;
- const void* code_begin;
- const void* code_end;
- } dynamic_code_generated;
- } _event_data;
- JvmtiDeferredEvent(Type t) : _type(t) {}
- public:
- JvmtiDeferredEvent() : _type(TYPE_NONE) {}
- static JvmtiDeferredEvent compiled_method_load_event(nmethod* nm)
- NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
- static JvmtiDeferredEvent compiled_method_unload_event(nmethod* nm,
- jmethodID id, const void* code) NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
- static JvmtiDeferredEvent dynamic_code_generated_event(
- const char* name, const void* begin, const void* end)
- NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
- void post() NOT_JVMTI_RETURN;
- };
- class JvmtiDeferredEventQueue : AllStatic {
- friend class JvmtiDeferredEvent;
- private:
- class QueueNode : public CHeapObj<mtInternal> {
- private:
- JvmtiDeferredEvent _event;
- QueueNode* _next;
- public:
- QueueNode(const JvmtiDeferredEvent& event)
- : _event(event), _next(NULL) {}
- const JvmtiDeferredEvent& event() const { return _event; }
- QueueNode* next() const { return _next; }
- void set_next(QueueNode* next) { _next = next; }
- };
- static QueueNode* _queue_head; // Hold Service_lock to access
- static QueueNode* _queue_tail; // Hold Service_lock to access
- static volatile QueueNode* _pending_list; // Uses CAS for read/update
- static void process_pending_events() NOT_JVMTI_RETURN;
- public:
- static bool has_events() NOT_JVMTI_RETURN_(false);
- static void enqueue(const JvmtiDeferredEvent& event) NOT_JVMTI_RETURN;
- static JvmtiDeferredEvent dequeue() NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
- static void add_pending_event(const JvmtiDeferredEvent&) NOT_JVMTI_RETURN;
- };
- #define NULL_CHECK(X, Y) if ((X) == NULL) { return (Y); }
- #endif // SHARE_VM_PRIMS_JVMTIIMPL_HPP
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiManageCapabilities.cpp
- #include "precompiled.hpp"
- #include "jvmtifiles/jvmtiEnv.hpp"
- #include "prims/jvmtiExport.hpp"
- #include "prims/jvmtiManageCapabilities.hpp"
- static const jint CAPA_SIZE = (JVMTI_INTERNAL_CAPABILITY_COUNT + 7) / 8;
- jvmtiCapabilities JvmtiManageCapabilities::always_capabilities;
- jvmtiCapabilities JvmtiManageCapabilities::onload_capabilities;
- jvmtiCapabilities JvmtiManageCapabilities::always_solo_capabilities;
- jvmtiCapabilities JvmtiManageCapabilities::onload_solo_capabilities;
- jvmtiCapabilities JvmtiManageCapabilities::always_solo_remaining_capabilities;
- jvmtiCapabilities JvmtiManageCapabilities::onload_solo_remaining_capabilities;
- jvmtiCapabilities JvmtiManageCapabilities::acquired_capabilities;
- void JvmtiManageCapabilities::initialize() {
- always_capabilities = init_always_capabilities();
- if (JvmtiEnv::get_phase() != JVMTI_PHASE_ONLOAD) {
- recompute_always_capabilities();
- }
- onload_capabilities = init_onload_capabilities();
- always_solo_capabilities = init_always_solo_capabilities();
- onload_solo_capabilities = init_onload_solo_capabilities();
- always_solo_remaining_capabilities = init_always_solo_capabilities();
- onload_solo_remaining_capabilities = init_onload_solo_capabilities();
- memset(&acquired_capabilities, 0, sizeof(acquired_capabilities));
- }
- void JvmtiManageCapabilities::recompute_always_capabilities() {
- if (!UseSharedSpaces) {
- jvmtiCapabilities jc = always_capabilities;
- jc.can_generate_all_class_hook_events = 1;
- always_capabilities = jc;
- }
- }
- jvmtiCapabilities JvmtiManageCapabilities::init_always_capabilities() {
- jvmtiCapabilities jc;
- memset(&jc, 0, sizeof(jc));
- jc.can_get_bytecodes = 1;
- jc.can_signal_thread = 1;
- jc.can_get_source_file_name = 1;
- jc.can_get_line_numbers = 1;
- jc.can_get_synthetic_attribute = 1;
- jc.can_get_monitor_info = 1;
- jc.can_get_constant_pool = 1;
- jc.can_generate_monitor_events = 1;
- jc.can_generate_garbage_collection_events = 1;
- jc.can_generate_compiled_method_load_events = 1;
- jc.can_generate_native_method_bind_events = 1;
- jc.can_generate_vm_object_alloc_events = 1;
- if (os::is_thread_cpu_time_supported()) {
- jc.can_get_current_thread_cpu_time = 1;
- jc.can_get_thread_cpu_time = 1;
- }
- jc.can_redefine_classes = 1;
- jc.can_redefine_any_class = 1;
- jc.can_retransform_classes = 1;
- jc.can_retransform_any_class = 1;
- jc.can_set_native_method_prefix = 1;
- jc.can_tag_objects = 1;
- jc.can_generate_object_free_events = 1;
- jc.can_generate_resource_exhaustion_heap_events = 1;
- jc.can_generate_resource_exhaustion_threads_events = 1;
- return jc;
- }
- jvmtiCapabilities JvmtiManageCapabilities::init_onload_capabilities() {
- jvmtiCapabilities jc;
- memset(&jc, 0, sizeof(jc));
- #ifndef ZERO
- jc.can_pop_frame = 1;
- jc.can_force_early_return = 1;
- #endif // !ZERO
- jc.can_get_source_debug_extension = 1;
- jc.can_access_local_variables = 1;
- jc.can_maintain_original_method_order = 1;
- jc.can_generate_all_class_hook_events = 1;
- jc.can_generate_single_step_events = 1;
- jc.can_generate_exception_events = 1;
- jc.can_generate_frame_pop_events = 1;
- jc.can_generate_method_entry_events = 1;
- jc.can_generate_method_exit_events = 1;
- jc.can_get_owned_monitor_info = 1;
- jc.can_get_owned_monitor_stack_depth_info = 1;
- jc.can_get_current_contended_monitor = 1;
- jc.can_tag_objects = 1; // TODO: this should have been removed
- jc.can_generate_object_free_events = 1; // TODO: this should have been removed
- return jc;
- }
- jvmtiCapabilities JvmtiManageCapabilities::init_always_solo_capabilities() {
- jvmtiCapabilities jc;
- memset(&jc, 0, sizeof(jc));
- jc.can_suspend = 1;
- return jc;
- }
- jvmtiCapabilities JvmtiManageCapabilities::init_onload_solo_capabilities() {
- jvmtiCapabilities jc;
- memset(&jc, 0, sizeof(jc));
- jc.can_generate_field_modification_events = 1;
- jc.can_generate_field_access_events = 1;
- jc.can_generate_breakpoint_events = 1;
- return jc;
- }
- jvmtiCapabilities *JvmtiManageCapabilities::either(const jvmtiCapabilities *a, const jvmtiCapabilities *b,
- jvmtiCapabilities *result) {
- char *ap = (char *)a;
- char *bp = (char *)b;
- char *resultp = (char *)result;
- for (int i = 0; i < CAPA_SIZE; ++i) {
- }
- return result;
- }
- jvmtiCapabilities *JvmtiManageCapabilities::both(const jvmtiCapabilities *a, const jvmtiCapabilities *b,
- jvmtiCapabilities *result) {
- char *ap = (char *)a;
- char *bp = (char *)b;
- char *resultp = (char *)result;
- for (int i = 0; i < CAPA_SIZE; ++i) {
- }
- return result;
- }
- jvmtiCapabilities *JvmtiManageCapabilities::exclude(const jvmtiCapabilities *a, const jvmtiCapabilities *b,
- jvmtiCapabilities *result) {
- char *ap = (char *)a;
- char *bp = (char *)b;
- char *resultp = (char *)result;
- for (int i = 0; i < CAPA_SIZE; ++i) {
- }
- return result;
- }
- bool JvmtiManageCapabilities::has_some(const jvmtiCapabilities *a) {
- char *ap = (char *)a;
- for (int i = 0; i < CAPA_SIZE; ++i) {
- if (*ap++ != 0) {
- return true;
- }
- }
- return false;
- }
- void JvmtiManageCapabilities::copy_capabilities(const jvmtiCapabilities *from, jvmtiCapabilities *to) {
- char *ap = (char *)from;
- char *resultp = (char *)to;
- for (int i = 0; i < CAPA_SIZE; ++i) {
- }
- }
- void JvmtiManageCapabilities::get_potential_capabilities(const jvmtiCapabilities *current,
- const jvmtiCapabilities *prohibited,
- jvmtiCapabilities *result) {
- exclude(&always_capabilities, prohibited, result);
- either(result, current, result);
- either(result, &always_solo_remaining_capabilities, result);
- if (JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) {
- either(result, &onload_capabilities, result);
- either(result, &onload_solo_remaining_capabilities, result);
- }
- }
- jvmtiError JvmtiManageCapabilities::add_capabilities(const jvmtiCapabilities *current,
- const jvmtiCapabilities *prohibited,
- const jvmtiCapabilities *desired,
- jvmtiCapabilities *result) {
- jvmtiCapabilities temp;
- get_potential_capabilities(current, prohibited, &temp);
- if (has_some(exclude(desired, &temp, &temp))) {
- return JVMTI_ERROR_NOT_AVAILABLE;
- }
- either(&acquired_capabilities, desired, &acquired_capabilities);
- both(&onload_capabilities, desired, &temp);
- either(&always_capabilities, &temp, &always_capabilities);
- exclude(&onload_capabilities, &temp, &onload_capabilities);
- both(&onload_solo_capabilities, desired, &temp);
- either(&always_solo_capabilities, &temp, &always_solo_capabilities);
- exclude(&onload_solo_capabilities, &temp, &onload_solo_capabilities);
- exclude(&always_solo_remaining_capabilities, desired, &always_solo_remaining_capabilities);
- exclude(&onload_solo_remaining_capabilities, desired, &onload_solo_remaining_capabilities);
- either(current, desired, result);
- update();
- return JVMTI_ERROR_NONE;
- }
- void JvmtiManageCapabilities::relinquish_capabilities(const jvmtiCapabilities *current,
- const jvmtiCapabilities *unwanted,
- jvmtiCapabilities *result) {
- jvmtiCapabilities to_trash;
- jvmtiCapabilities temp;
- both(current, unwanted, &to_trash);
- either(&always_solo_remaining_capabilities, both(&always_solo_capabilities, &to_trash, &temp),
- &always_solo_remaining_capabilities);
- either(&onload_solo_remaining_capabilities, both(&onload_solo_capabilities, &to_trash, &temp),
- &onload_solo_remaining_capabilities);
- update();
- exclude(current, unwanted, result);
- }
- void JvmtiManageCapabilities::update() {
- jvmtiCapabilities avail;
- either(&always_capabilities, &always_solo_capabilities, &avail);
- bool interp_events =
- avail.can_generate_field_access_events ||
- avail.can_generate_field_modification_events ||
- avail.can_generate_single_step_events ||
- avail.can_generate_frame_pop_events ||
- avail.can_generate_method_entry_events ||
- avail.can_generate_method_exit_events;
- bool enter_all_methods =
- interp_events ||
- avail.can_generate_breakpoint_events;
- if (enter_all_methods) {
- UseFastEmptyMethods = false;
- UseFastAccessorMethods = false;
- }
- if (avail.can_generate_breakpoint_events) {
- RewriteFrequentPairs = false;
- }
- if ((avail.can_redefine_classes || avail.can_retransform_classes) &&
- JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) {
- JvmtiExport::set_all_dependencies_are_recorded(true);
- }
- JvmtiExport::set_can_get_source_debug_extension(avail.can_get_source_debug_extension);
- JvmtiExport::set_can_maintain_original_method_order(avail.can_maintain_original_method_order);
- JvmtiExport::set_can_post_interpreter_events(interp_events);
- JvmtiExport::set_can_hotswap_or_post_breakpoint(
- avail.can_generate_breakpoint_events ||
- avail.can_redefine_classes ||
- avail.can_retransform_classes);
- JvmtiExport::set_can_modify_any_class(
- avail.can_generate_breakpoint_events ||
- avail.can_generate_all_class_hook_events);
- JvmtiExport::set_can_walk_any_space(
- avail.can_tag_objects); // disable sharing in onload phase
- JvmtiExport::set_can_access_local_variables(
- avail.can_access_local_variables ||
- avail.can_generate_breakpoint_events ||
- avail.can_generate_frame_pop_events);
- JvmtiExport::set_can_post_on_exceptions(
- avail.can_generate_exception_events ||
- avail.can_generate_frame_pop_events ||
- avail.can_generate_method_exit_events);
- JvmtiExport::set_can_post_breakpoint(avail.can_generate_breakpoint_events);
- JvmtiExport::set_can_post_field_access(avail.can_generate_field_access_events);
- JvmtiExport::set_can_post_field_modification(avail.can_generate_field_modification_events);
- JvmtiExport::set_can_post_method_entry(avail.can_generate_method_entry_events);
- JvmtiExport::set_can_post_method_exit(avail.can_generate_method_exit_events ||
- avail.can_generate_frame_pop_events);
- JvmtiExport::set_can_pop_frame(avail.can_pop_frame);
- JvmtiExport::set_can_force_early_return(avail.can_force_early_return);
- JvmtiExport::set_should_clean_up_heap_objects(avail.can_generate_breakpoint_events);
- }
- #ifndef PRODUCT
- void JvmtiManageCapabilities:: print(const jvmtiCapabilities* cap) {
- tty->print_cr("----- capabilities -----");
- if (cap->can_tag_objects)
- tty->print_cr("can_tag_objects");
- if (cap->can_generate_field_modification_events)
- tty->print_cr("can_generate_field_modification_events");
- if (cap->can_generate_field_access_events)
- tty->print_cr("can_generate_field_access_events");
- if (cap->can_get_bytecodes)
- tty->print_cr("can_get_bytecodes");
- if (cap->can_get_synthetic_attribute)
- tty->print_cr("can_get_synthetic_attribute");
- if (cap->can_get_owned_monitor_info)
- tty->print_cr("can_get_owned_monitor_info");
- if (cap->can_get_current_contended_monitor)
- tty->print_cr("can_get_current_contended_monitor");
- if (cap->can_get_monitor_info)
- tty->print_cr("can_get_monitor_info");
- if (cap->can_get_constant_pool)
- tty->print_cr("can_get_constant_pool");
- if (cap->can_pop_frame)
- tty->print_cr("can_pop_frame");
- if (cap->can_force_early_return)
- tty->print_cr("can_force_early_return");
- if (cap->can_redefine_classes)
- tty->print_cr("can_redefine_classes");
- if (cap->can_retransform_classes)
- tty->print_cr("can_retransform_classes");
- if (cap->can_signal_thread)
- tty->print_cr("can_signal_thread");
- if (cap->can_get_source_file_name)
- tty->print_cr("can_get_source_file_name");
- if (cap->can_get_line_numbers)
- tty->print_cr("can_get_line_numbers");
- if (cap->can_get_source_debug_extension)
- tty->print_cr("can_get_source_debug_extension");
- if (cap->can_access_local_variables)
- tty->print_cr("can_access_local_variables");
- if (cap->can_maintain_original_method_order)
- tty->print_cr("can_maintain_original_method_order");
- if (cap->can_generate_single_step_events)
- tty->print_cr("can_generate_single_step_events");
- if (cap->can_generate_exception_events)
- tty->print_cr("can_generate_exception_events");
- if (cap->can_generate_frame_pop_events)
- tty->print_cr("can_generate_frame_pop_events");
- if (cap->can_generate_breakpoint_events)
- tty->print_cr("can_generate_breakpoint_events");
- if (cap->can_suspend)
- tty->print_cr("can_suspend");
- if (cap->can_redefine_any_class )
- tty->print_cr("can_redefine_any_class");
- if (cap->can_retransform_any_class )
- tty->print_cr("can_retransform_any_class");
- if (cap->can_get_current_thread_cpu_time)
- tty->print_cr("can_get_current_thread_cpu_time");
- if (cap->can_get_thread_cpu_time)
- tty->print_cr("can_get_thread_cpu_time");
- if (cap->can_generate_method_entry_events)
- tty->print_cr("can_generate_method_entry_events");
- if (cap->can_generate_method_exit_events)
- tty->print_cr("can_generate_method_exit_events");
- if (cap->can_generate_all_class_hook_events)
- tty->print_cr("can_generate_all_class_hook_events");
- if (cap->can_generate_compiled_method_load_events)
- tty->print_cr("can_generate_compiled_method_load_events");
- if (cap->can_generate_monitor_events)
- tty->print_cr("can_generate_monitor_events");
- if (cap->can_generate_vm_object_alloc_events)
- tty->print_cr("can_generate_vm_object_alloc_events");
- if (cap->can_generate_native_method_bind_events)
- tty->print_cr("can_generate_native_method_bind_events");
- if (cap->can_generate_garbage_collection_events)
- tty->print_cr("can_generate_garbage_collection_events");
- if (cap->can_generate_object_free_events)
- tty->print_cr("can_generate_object_free_events");
- if (cap->can_generate_resource_exhaustion_heap_events)
- tty->print_cr("can_generate_resource_exhaustion_heap_events");
- if (cap->can_generate_resource_exhaustion_threads_events)
- tty->print_cr("can_generate_resource_exhaustion_threads_events");
- }
- #endif
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiManageCapabilities.hpp
- #ifndef SHARE_VM_PRIMS_JVMTIMANAGECAPABILITIES_HPP
- #define SHARE_VM_PRIMS_JVMTIMANAGECAPABILITIES_HPP
- #include "jvmtifiles/jvmti.h"
- #include "memory/allocation.hpp"
- class JvmtiManageCapabilities : public AllStatic {
- private:
- static jvmtiCapabilities always_capabilities;
- static jvmtiCapabilities onload_capabilities;
- static jvmtiCapabilities always_solo_capabilities;
- static jvmtiCapabilities onload_solo_capabilities;
- static jvmtiCapabilities always_solo_remaining_capabilities;
- static jvmtiCapabilities onload_solo_remaining_capabilities;
- static jvmtiCapabilities acquired_capabilities;
- static jvmtiCapabilities *either(const jvmtiCapabilities *a, const jvmtiCapabilities *b, jvmtiCapabilities *result);
- static jvmtiCapabilities *both(const jvmtiCapabilities *a, const jvmtiCapabilities *b, jvmtiCapabilities *result);
- static jvmtiCapabilities *exclude(const jvmtiCapabilities *a, const jvmtiCapabilities *b, jvmtiCapabilities *result);
- static bool has_some(const jvmtiCapabilities *a);
- static void update();
- static jvmtiCapabilities init_always_capabilities();
- static jvmtiCapabilities init_onload_capabilities();
- static jvmtiCapabilities init_always_solo_capabilities();
- static jvmtiCapabilities init_onload_solo_capabilities();
- public:
- static void initialize();
- static void recompute_always_capabilities();
- static void get_potential_capabilities(const jvmtiCapabilities *current,
- const jvmtiCapabilities *prohibited,
- jvmtiCapabilities *result);
- static jvmtiError add_capabilities(const jvmtiCapabilities *current,
- const jvmtiCapabilities *prohibited,
- const jvmtiCapabilities *desired,
- jvmtiCapabilities *result);
- static void relinquish_capabilities(const jvmtiCapabilities *current,
- const jvmtiCapabilities *unwanted,
- jvmtiCapabilities *result);
- static void copy_capabilities(const jvmtiCapabilities *from, jvmtiCapabilities *to);
- #ifndef PRODUCT
- static void print(const jvmtiCapabilities* caps);
- #endif
- };
- #endif // SHARE_VM_PRIMS_JVMTIMANAGECAPABILITIES_HPP
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiRawMonitor.cpp
- #include "precompiled.hpp"
- #include "prims/jvmtiRawMonitor.hpp"
- #include "runtime/interfaceSupport.hpp"
- #include "runtime/orderAccess.inline.hpp"
- #include "runtime/thread.inline.hpp"
- GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1,true);
- void JvmtiPendingMonitors::transition_raw_monitors() {
- assert((Threads::number_of_threads()==1),
- "Java thread has not created yet or more than one java thread \
- is running. Raw monitor transition will not work");
- JavaThread *current_java_thread = JavaThread::current();
- assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
- {
- ThreadBlockInVM __tbivm(current_java_thread);
- for(int i=0; i< count(); i++) {
- JvmtiRawMonitor *rmonitor = monitors()->at(i);
- int r = rmonitor->raw_enter(current_java_thread);
- assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
- }
- }
- dispose();
- }
- JvmtiRawMonitor::JvmtiRawMonitor(const char *name) {
- #ifdef ASSERT
- _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name);
- #else
- _name = NULL;
- #endif
- _magic = JVMTI_RM_MAGIC;
- }
- JvmtiRawMonitor::~JvmtiRawMonitor() {
- #ifdef ASSERT
- FreeHeap(_name);
- #endif
- _magic = 0;
- }
- bool
- JvmtiRawMonitor::is_valid() {
- int value = 0;
- switch (sizeof(_magic)) {
- case 2:
- value = Bytes::get_native_u2((address)&_magic);
- break;
- case 4:
- value = Bytes::get_native_u4((address)&_magic);
- break;
- case 8:
- value = Bytes::get_native_u8((address)&_magic);
- break;
- default:
- guarantee(false, "_magic field is an unexpected size");
- }
- return value == JVMTI_RM_MAGIC;
- }
- int JvmtiRawMonitor::SimpleEnter (Thread * Self) {
- for (;;) {
- if (Atomic::cmpxchg_ptr (Self, &_owner, NULL) == NULL) {
- return OS_OK ;
- }
- ObjectWaiter Node (Self) ;
- Self->_ParkEvent->reset() ; // strictly optional
- Node.TState = ObjectWaiter::TS_ENTER ;
- RawMonitor_lock->lock_without_safepoint_check() ;
- Node._next = _EntryList ;
- _EntryList = &Node ;
- OrderAccess::fence() ;
- if (_owner == NULL && Atomic::cmpxchg_ptr (Self, &_owner, NULL) == NULL) {
- _EntryList = Node._next ;
- RawMonitor_lock->unlock() ;
- return OS_OK ;
- }
- RawMonitor_lock->unlock() ;
- while (Node.TState == ObjectWaiter::TS_ENTER) {
- Self->_ParkEvent->park() ;
- }
- }
- }
- int JvmtiRawMonitor::SimpleExit (Thread * Self) {
- guarantee (_owner == Self, "invariant") ;
- OrderAccess::release_store_ptr (&_owner, NULL) ;
- OrderAccess::fence() ;
- if (_EntryList == NULL) return OS_OK ;
- ObjectWaiter * w ;
- RawMonitor_lock->lock_without_safepoint_check() ;
- w = _EntryList ;
- if (w != NULL) {
- _EntryList = w->_next ;
- }
- RawMonitor_lock->unlock() ;
- if (w != NULL) {
- guarantee (w ->TState == ObjectWaiter::TS_ENTER, "invariant") ;
- ParkEvent * ev = w->_event ;
- w->TState = ObjectWaiter::TS_RUN ;
- OrderAccess::fence() ;
- ev->unpark() ;
- }
- return OS_OK ;
- }
- int JvmtiRawMonitor::SimpleWait (Thread * Self, jlong millis) {
- guarantee (_owner == Self , "invariant") ;
- guarantee (_recursions == 0, "invariant") ;
- ObjectWaiter Node (Self) ;
- Node._notified = 0 ;
- Node.TState = ObjectWaiter::TS_WAIT ;
- RawMonitor_lock->lock_without_safepoint_check() ;
- Node._next = _WaitSet ;
- _WaitSet = &Node ;
- RawMonitor_lock->unlock() ;
- SimpleExit (Self) ;
- guarantee (_owner != Self, "invariant") ;
- int ret = OS_OK ;
- if (millis <= 0) {
- Self->_ParkEvent->park();
- } else {
- ret = Self->_ParkEvent->park(millis);
- }
- if (Node.TState == ObjectWaiter::TS_WAIT) {
- RawMonitor_lock->lock_without_safepoint_check() ;
- if (Node.TState == ObjectWaiter::TS_WAIT) {
- ObjectWaiter * p ;
- ObjectWaiter * q = NULL ;
- for (p = _WaitSet ; p != &Node; p = p->_next) {
- q = p ;
- }
- guarantee (p == &Node, "invariant") ;
- if (q == NULL) {
- guarantee (p == _WaitSet, "invariant") ;
- _WaitSet = p->_next ;
- } else {
- guarantee (p == q->_next, "invariant") ;
- q->_next = p->_next ;
- }
- Node.TState = ObjectWaiter::TS_RUN ;
- }
- RawMonitor_lock->unlock() ;
- }
- guarantee (Node.TState == ObjectWaiter::TS_RUN, "invariant") ;
- SimpleEnter (Self) ;
- guarantee (_owner == Self, "invariant") ;
- guarantee (_recursions == 0, "invariant") ;
- return ret ;
- }
- int JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) {
- guarantee (_owner == Self, "invariant") ;
- if (_WaitSet == NULL) return OS_OK ;
- ParkEvent * ev = NULL ; // consider using a small auto array ...
- RawMonitor_lock->lock_without_safepoint_check() ;
- for (;;) {
- ObjectWaiter * w = _WaitSet ;
- if (w == NULL) break ;
- _WaitSet = w->_next ;
- if (ev != NULL) { ev->unpark(); ev = NULL; }
- ev = w->_event ;
- OrderAccess::loadstore() ;
- w->TState = ObjectWaiter::TS_RUN ;
- OrderAccess::storeload();
- if (!All) break ;
- }
- RawMonitor_lock->unlock() ;
- if (ev != NULL) ev->unpark();
- return OS_OK ;
- }
- int JvmtiRawMonitor::raw_enter(TRAPS) {
- TEVENT (raw_enter) ;
- void * Contended ;
- JavaThread * jt = (JavaThread *)THREAD;
- if (THREAD->is_Java_thread()) {
- jt->SR_lock()->lock_without_safepoint_check();
- while (jt->is_external_suspend()) {
- jt->SR_lock()->unlock();
- jt->java_suspend_self();
- jt->SR_lock()->lock_without_safepoint_check();
- }
- Contended = Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) ;
- jt->SR_lock()->unlock();
- } else {
- Contended = Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) ;
- }
- if (Contended == THREAD) {
- _recursions ++ ;
- return OM_OK ;
- }
- if (Contended == NULL) {
- guarantee (_owner == THREAD, "invariant") ;
- guarantee (_recursions == 0, "invariant") ;
- return OM_OK ;
- }
- THREAD->set_current_pending_monitor(this);
- if (!THREAD->is_Java_thread()) {
- assert(THREAD->is_VM_thread(), "must be VM thread");
- SimpleEnter (THREAD) ;
- } else {
- guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
- for (;;) {
- jt->set_suspend_equivalent();
- SimpleEnter (THREAD) ;
- if (!jt->handle_special_suspend_equivalent_condition()) break ;
- SimpleExit (THREAD) ;
- jt->java_suspend_self();
- }
- assert(_owner == THREAD, "Fatal error with monitor owner!");
- assert(_recursions == 0, "Fatal error with monitor recursions!");
- }
- THREAD->set_current_pending_monitor(NULL);
- guarantee (_recursions == 0, "invariant") ;
- return OM_OK;
- }
- int JvmtiRawMonitor::raw_exit(TRAPS) {
- TEVENT (raw_exit) ;
- if (THREAD != _owner) {
- return OM_ILLEGAL_MONITOR_STATE;
- }
- if (_recursions > 0) {
- --_recursions ;
- return OM_OK ;
- }
- void * List = _EntryList ;
- SimpleExit (THREAD) ;
- return OM_OK;
- }
- int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, TRAPS) {
- TEVENT (raw_wait) ;
- if (THREAD != _owner) {
- return OM_ILLEGAL_MONITOR_STATE;
- }
- THREAD->_ParkEvent->reset() ;
- OrderAccess::fence() ;
- if (interruptible && Thread::is_interrupted(THREAD, true)) {
- return OM_INTERRUPTED;
- }
- intptr_t save = _recursions ;
- _recursions = 0 ;
- _waiters ++ ;
- if (THREAD->is_Java_thread()) {
- guarantee (((JavaThread *) THREAD)->thread_state() == _thread_blocked, "invariant") ;
- ((JavaThread *)THREAD)->set_suspend_equivalent();
- }
- int rv = SimpleWait (THREAD, millis) ;
- _recursions = save ;
- _waiters -- ;
- guarantee (THREAD == _owner, "invariant") ;
- if (THREAD->is_Java_thread()) {
- JavaThread * jSelf = (JavaThread *) THREAD ;
- for (;;) {
- if (!jSelf->handle_special_suspend_equivalent_condition()) break ;
- SimpleExit (THREAD) ;
- jSelf->java_suspend_self();
- SimpleEnter (THREAD) ;
- jSelf->set_suspend_equivalent() ;
- }
- }
- guarantee (THREAD == _owner, "invariant") ;
- if (interruptible && Thread::is_interrupted(THREAD, true)) {
- return OM_INTERRUPTED;
- }
- return OM_OK ;
- }
- int JvmtiRawMonitor::raw_notify(TRAPS) {
- TEVENT (raw_notify) ;
- if (THREAD != _owner) {
- return OM_ILLEGAL_MONITOR_STATE;
- }
- SimpleNotify (THREAD, false) ;
- return OM_OK;
- }
- int JvmtiRawMonitor::raw_notifyAll(TRAPS) {
- TEVENT (raw_notifyAll) ;
- if (THREAD != _owner) {
- return OM_ILLEGAL_MONITOR_STATE;
- }
- SimpleNotify (THREAD, true) ;
- return OM_OK;
- }
- C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiRawMonitor.hpp
- #ifndef SHARE_VM_PRIMS_JVMTIRAWMONITOR_HPP
- #define SHARE_VM_PRIMS_JVMTIRAWMONITOR_HPP
- #include "runtime/objectMonitor.hpp"
- #include "utilities/growableArray.hpp"
- class JvmtiRawMonitor : public ObjectMonitor {
- private:
- int _magic;
- char * _name;
- enum { JVMTI_RM_MAGIC = (int)(('T' << 24) | ('I' << 16) | ('R' << 8) | 'M') };
- int SimpleEnter (Thread * Self) ;
- int SimpleExit (Thread * Self) ;
- int SimpleWait (Thread * Self, jlong millis) ;
- int SimpleNotify (Thread * Self, bool All) ;
- public:
- JvmtiRawMonitor(const char *name);
- ~JvmtiRawMonitor();
- int raw_enter(TRAPS);
- int raw_exit(TRAPS);
- int raw_wait(jlong millis, bool interruptable, TRAPS);
- int raw_notify(TRAPS);
- int raw_notifyAll(TRAPS);
- int magic() { return _magic; }
- const char *get_name() { return _name; }
- bool is_valid();
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。