Beispiel #1
0
void
JvmtiEnvBase::initialize() {
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");

  // Add this environment to the end of the environment list (order is important)
  {
    // This block of code must not contain any safepoints, as list deallocation
    // (which occurs at a safepoint) cannot occur simultaneously with this list
    // addition.  Note: No_Safepoint_Verifier cannot, currently, be used before
    // threads exist.
    JvmtiEnvIterator it;
    JvmtiEnvBase *previous_env = NULL;
    for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
      previous_env = env;
    }
    if (previous_env == NULL) {
      _head_environment = this;
    } else {
      previous_env->set_next_environment(this);
    }
  }

  if (_globally_initialized == false) {
    globally_initialize();
  }
}
Beispiel #2
0
void
JvmtiEnvBase::periodic_clean_up() {
  assert(SafepointSynchronize::is_at_safepoint(), "sanity check");

  // JvmtiEnvBase reference is saved in JvmtiEnvThreadState. So
  // clean up JvmtiThreadState before deleting JvmtiEnv pointer.
  JvmtiThreadState::periodic_clean_up();

  // Unlink all invalid environments from the list of environments
  // and deallocate them
  JvmtiEnvIterator it;
  JvmtiEnvBase* previous_env = NULL;
  JvmtiEnvBase* env = it.first();
  while (env != NULL) {
    if (env->is_valid()) {
      previous_env = env;
      env = it.next(env);
    } else {
      // This one isn't valid, remove it from the list and deallocate it
      JvmtiEnvBase* defunct_env = env;
      env = it.next(env);
      if (previous_env == NULL) {
        _head_environment = env;
      } else {
        previous_env->set_next_environment(env);
      }
      delete defunct_env;
    }
  }

}
JvmtiThreadState::JvmtiThreadState(JavaThread* thread)
  : _thread_event_enable() {
  assert(JvmtiThreadState_lock->is_locked(), "sanity check");
  _thread               = thread;
  _exception_detected   = false;
  _exception_caught     = false;
  _debuggable           = true;
  _hide_single_stepping = false;
  _hide_level           = 0;
  _pending_step_for_popframe = false;
  _class_being_redefined = NULL;
  _class_load_kind = jvmti_class_load_kind_load;
  _head_env_thread_state = NULL;
  _dynamic_code_event_collector = NULL;
  _vm_object_alloc_event_collector = NULL;
  _the_class_for_redefinition_verification = NULL;
  _scratch_class_for_redefinition_verification = NULL;
  _cur_stack_depth = UNKNOWN_STACK_DEPTH;

  // JVMTI ForceEarlyReturn support
  _pending_step_for_earlyret = false;
  _earlyret_state = earlyret_inactive;
  _earlyret_tos = ilgl;
  _earlyret_value.j = 0L;
  _earlyret_oop = NULL;

  // add all the JvmtiEnvThreadState to the new JvmtiThreadState
  {
    JvmtiEnvIterator it;
    for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
      if (env->is_valid()) {
        add_env(env);
      }
    }
  }

  // link us into the list
  {
    // The thread state list manipulation code must not have safepoints.
    // See periodic_clean_up().
    debug_only(No_Safepoint_Verifier nosafepoint;)

    _prev = NULL;
    _next = _head;
    if (_head != NULL) {
      _head->_prev = this;
    }
    _head = this;
  }
// Compute truly enabled events - meaning if the event can and could be
// sent.  An event is truly enabled if it is user enabled on the thread
// or globally user enabled, but only if there is a callback or event hook
// for it and, for field watch and frame pop, one has been set.
// Compute if truly enabled, per thread, per environment, per combination
// (thread x environment), and overall.  These merges are true if any is true.
// True per thread if some environment has callback set and the event is globally
// enabled or enabled for this thread.
// True per environment if the callback is set and the event is globally
// enabled in this environment or enabled for any thread in this environment.
// True per combination if the environment has the callback set and the
// event is globally enabled in this environment or the event is enabled
// for this thread and environment.
//
// All states transitions dependent on these transitions are also handled here.
void
JvmtiEventControllerPrivate::recompute_enabled() {
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");

  // event enabled for any thread in any environment
  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 " UINT64_FORMAT_X, was_any_env_thread_enabled));

  // compute non-thread-filters events.
  // This must be done separately from thread-filtered events, since some
  // events can occur before any threads exist.
  JvmtiEnvIterator it;
  for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
    any_env_thread_enabled |= recompute_env_enabled(env);
  }

  // We need to create any missing jvmti_thread_state if there are globally set thread
  // filtered events and there weren't last time
  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()) {
        // state_for_while_locked() makes tp->is_exiting() check
        JvmtiThreadState::state_for_while_locked(tp);  // create the thread state if missing
      }
    }// release Threads_lock
  }

  // compute and set thread-filtered events
  for (JvmtiThreadState *state = JvmtiThreadState::first(); state != NULL; state = state->next()) {
    any_env_thread_enabled |= recompute_thread_enabled(state);
  }

  // set universal state (across all envs and threads)
  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);

    // need this if we want thread events or we need them to init data
    JvmtiExport::set_should_post_thread_life((any_env_thread_enabled & NEED_THREAD_LIFE_EVENTS) != 0);

    // If single stepping is turned on or off, execute the VM op to change it.
    if (delta & SINGLE_STEP_BIT) {
      switch (JvmtiEnv::get_phase()) {
      case JVMTI_PHASE_DEAD:
        // If the VM is dying we can't execute VM ops
        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;
      }
    }

    // set global truly enabled, that is, any thread in any environment
    JvmtiEventController::_universal_global_event_enabled.set_bits(any_env_thread_enabled);

    // set global should_post_on_exceptions
    JvmtiExport::set_should_post_on_exceptions((any_env_thread_enabled & SHOULD_POST_ON_EXCEPTIONS_BITS) != 0);

  }

  EC_TRACE(("JVMTI [-] # recompute enabled - after " UINT64_FORMAT_X, any_env_thread_enabled));
}