Пример #1
0
//
// Reclaim all unused buckets.
//
void DependencyContext::expunge_stale_entries() {
  assert_locked_or_safepoint(CodeCache_lock);
  if (!has_stale_entries()) {
    assert(!find_stale_entries(), "inconsistent info");
    return;
  }
  nmethodBucket* first = dependencies();
  nmethodBucket* last = NULL;
  int removed = 0;
  for (nmethodBucket* b = first; b != NULL;) {
    assert(b->count() >= 0, "bucket count: %d", b->count());
    nmethodBucket* next = b->next();
    if (b->count() == 0) {
      if (last == NULL) {
        first = next;
      } else {
        last->set_next(next);
      }
      removed++;
      delete b;
      // last stays the same.
    } else {
      last = b;
    }
    b = next;
  }
  set_dependencies(first);
  set_has_stale_entries(false);
  if (UsePerfData && removed > 0) {
    _perf_total_buckets_deallocated_count->inc(removed);
    _perf_total_buckets_stale_count->dec(removed);
  }
}
Пример #2
0
	void on_property_deleted(iproperty* Property)
	{
		dependencies_t::iterator dependency = dependencies.find(Property);
		if(dependency != dependencies.end())
		{
			if(state_recorder && state_recorder->current_change_set())
			{
				dependencies_t old_dependencies;
				old_dependencies.insert(*dependency);
				state_recorder->current_change_set()->record_old_state(new set_dependencies_container(*this, old_dependencies));
				state_recorder->current_change_set()->record_new_state(new delete_property_container(*this, Property));
			}
	
			dependencies.erase(dependency);
		}
		
		m_delete_connections[Property].disconnect();
		m_delete_connections.erase(Property);

		dependencies_t new_dependencies;
		for(dependencies_t::iterator dependency = dependencies.begin(); dependency != dependencies.end(); ++dependency)
		{
			if(dependency->second == Property)
			{
				dependency->first->property_set_dependency(0);
				new_dependencies.insert(std::make_pair(dependency->first, static_cast<iproperty*>(0)));
			}
		}

		new_dependencies[Property] = 0;
		set_dependencies(new_dependencies);
	}
Пример #3
0
void DependencyContext::wipe() {
  assert_locked_or_safepoint(CodeCache_lock);
  nmethodBucket* b = dependencies();
  set_dependencies(NULL);
  set_has_stale_entries(false);
  while (b != NULL) {
    nmethodBucket* next = b->next();
    delete b;
    b = next;
  }
}
Пример #4
0
//
// Add an nmethod to the dependency context.
// It's possible that an nmethod has multiple dependencies on a klass
// so a count is kept for each bucket to guarantee that creation and
// deletion of dependencies is consistent.
//
void DependencyContext::add_dependent_nmethod(nmethod* nm, bool expunge) {
  assert_lock_strong(CodeCache_lock);
  for (nmethodBucket* b = dependencies(); b != NULL; b = b->next()) {
    if (nm == b->get_nmethod()) {
      b->increment();
      return;
    }
  }
  set_dependencies(new nmethodBucket(nm, dependencies()));
  if (UsePerfData) {
    _perf_total_buckets_allocated_count->inc();
  }
  if (expunge) {
    // Remove stale entries from the list.
    expunge_stale_entries();
  }
}
Пример #5
0
//
// Remove an nmethod dependency from the context.
// Decrement count of the nmethod in the dependency list and, optionally, remove
// the bucket completely when the count goes to 0.  This method must find
// a corresponding bucket otherwise there's a bug in the recording of dependencies.
// Can be called concurrently by parallel GC threads.
//
void DependencyContext::remove_dependent_nmethod(nmethod* nm, bool expunge) {
  assert_locked_or_safepoint(CodeCache_lock);
  nmethodBucket* first = dependencies();
  nmethodBucket* last = NULL;
  for (nmethodBucket* b = first; b != NULL; b = b->next()) {
    if (nm == b->get_nmethod()) {
      int val = b->decrement();
      guarantee(val >= 0, "Underflow: %d", val);
      if (val == 0) {
        if (expunge) {
          if (last == NULL) {
            set_dependencies(b->next());
          } else {
            last->set_next(b->next());
          }
          delete b;
          if (UsePerfData) {
            _perf_total_buckets_deallocated_count->inc();
          }
        } else {
          // Mark the context as having stale entries, since it is not safe to
          // expunge the list right now.
          set_has_stale_entries(true);
          if (UsePerfData) {
            _perf_total_buckets_stale_count->inc();
            _perf_total_buckets_stale_acc_count->inc();
          }
        }
      }
      if (expunge) {
        // Remove stale entries from the list.
        expunge_stale_entries();
      }
      return;
    }
    last = b;
  }
#ifdef ASSERT
  tty->print_raw_cr("### can't find dependent nmethod");
  nm->print();
#endif // ASSERT
  ShouldNotReachHere();
}
Пример #6
0
//
// Invalidate all dependencies in the context
int DependencyContext::remove_all_dependents() {
  assert_locked_or_safepoint(CodeCache_lock);
  nmethodBucket* b = dependencies();
  set_dependencies(NULL);
  int marked = 0;
  int removed = 0;
  while (b != NULL) {
    nmethod* nm = b->get_nmethod();
    if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization()) {
      nm->mark_for_deoptimization();
      marked++;
    }
    nmethodBucket* next = b->next();
    removed++;
    delete b;
    b = next;
  }
  set_has_stale_entries(false);
  if (UsePerfData && removed > 0) {
    _perf_total_buckets_deallocated_count->inc(removed);
  }
  return marked;
}
Пример #7
0
void pipeline::connect(iproperty& From, iproperty& To)
{
	dependencies_t dependencies;
	dependencies.insert(std::make_pair(&To, &From));
	set_dependencies(dependencies);
}
Пример #8
0
int
main (int argc, char **argv)
{
  int command_number = 1;
  bool print_tree = false;
  bool time_travel = false;
  int **dependencies;
  int i, j, status, wait_val;
  pid_t* pids;
  bool can_run, finished;
  command_t* commands;
  program_name = argv[0];

  for (;;)
    switch (getopt (argc, argv, "pt"))
      {
      case 'p': print_tree = true; break;
      case 't': time_travel = true; break;
      default: usage (); break;
      case -1: goto options_exhausted;
      }
 options_exhausted:;

  // There must be exactly one file argument.
  if (optind != argc - 1)
    usage ();

  script_name = argv[optind];
  FILE *script_stream = fopen (script_name, "r");
  if (! script_stream)
    error (1, errno, "%s: cannot open", script_name);
  command_stream_t command_stream =
    make_command_stream (get_next_byte, script_stream);

  if (time_travel)
  {
    commands = command_stream->commands;
    dependencies = set_dependencies(commands, command_stream->num_commands);
    pids = (pid_t*) checked_malloc(sizeof(pid_t) * command_stream->num_commands);
    for (i = 0; i <command_stream->num_commands; i++)
      pids[i] = -1;
  }

  command_t last_command = NULL;
  command_t command;

  if (print_tree || !time_travel)
  {
    while ((command = read_command_stream (command_stream)))
      {
        if (print_tree)
  	{
  	  printf ("# %d\n", command_number++);
  	  print_command (command);
  	}
        else
  	{
  	  last_command = command;
  	  execute_command (command);
  	}
      }
  }

  else
  {
    for(;;)
    {
      finished = true;
      for (i = 0; i < command_stream->num_commands; i++)
      {
        if (pids[i] == -1)
        {
          can_run = true;
          for (j = 0; dependencies[i][j] != -1; j++)
            if (commands[dependencies[i][j]]->status == -1)
                {
                  can_run = false;
                  break;
                }

          if (can_run)
          {
            pids[i] = fork();
            if (pids[i]== -1)
              error(1, errno, "Error forking process");

            if (pids[i] == 0)
            {
              execute_command(commands[i]);
              exit(commands[i]->status);
            }
          }
        }
      }

      for (i = 0; i < command_stream->num_commands; i++)
      {
        if (pids[i] != -1)
        {
          wait_val = waitpid(pids[i], &status, WNOHANG);

          if (wait_val == 0)
            finished = false;

          else
            commands[i]->status = WEXITSTATUS(status);
        }

        else
          finished = false;
      }
      if (finished)
      {
        last_command = commands[command_stream->num_commands-1];
        break;
      }
    }
  }


  free_stream(command_stream);
  if (time_travel)
  {
    free(pids);
    for (i = 0; i<command_stream->num_commands; i++)
      free(dependencies[i]);
    free(dependencies);
  }
  return print_tree || !last_command ? 0 : command_status (last_command);
}