view src/share/vm/runtime/simpleThresholdPolicy.hpp @ 3979:4dfb2df418f2

6484982: G1: process references during evacuation pauses Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate. Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
author johnc
date Thu, 22 Sep 2011 10:57:37 -0700
parents 43f9d800f276
children 973293defacd
line wrap: on
line source

/*
 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_RUNTIME_SIMPLETHRESHOLDPOLICY_HPP
#define SHARE_VM_RUNTIME_SIMPLETHRESHOLDPOLICY_HPP

#include "code/nmethod.hpp"
#include "oops/methodDataOop.hpp"
#include "runtime/compilationPolicy.hpp"
#include "utilities/globalDefinitions.hpp"

class CompileTask;
class CompileQueue;

class SimpleThresholdPolicy : public CompilationPolicy {
  int _c1_count, _c2_count;

  // Check if the counter is big enough and set carry (effectively infinity).
  inline void set_carry_if_necessary(InvocationCounter *counter);
  // Set carry flags in the counters (in methodOop and MDO).
  inline void handle_counter_overflow(methodOop method);
  // Call and loop predicates determine whether a transition to a higher compilation
  // level should be performed (pointers to predicate functions are passed to common_TF().
  // Predicates also take compiler load into account.
  typedef bool (SimpleThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level);
  bool call_predicate(int i, int b, CompLevel cur_level);
  bool loop_predicate(int i, int b, CompLevel cur_level);
  // Common transition function. Given a predicate determines if a method should transition to another level.
  CompLevel common(Predicate p, methodOop method, CompLevel cur_level);
  // Transition functions.
  // call_event determines if a method should be compiled at a different
  // level with a regular invocation entry.
  CompLevel call_event(methodOop method, CompLevel cur_level);
  // loop_event checks if a method should be OSR compiled at a different
  // level.
  CompLevel loop_event(methodOop method, CompLevel cur_level);

protected:
  int c1_count() const     { return _c1_count; }
  int c2_count() const     { return _c2_count; }
  void set_c1_count(int x) { _c1_count = x;    }
  void set_c2_count(int x) { _c2_count = x;    }

  enum EventType { CALL, LOOP, COMPILE, REMOVE_FROM_QUEUE, UPDATE_IN_QUEUE, REPROFILE, MAKE_NOT_ENTRANT };
  void print_event(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level);
  // Print policy-specific information if necessary
  virtual void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level) { }
  // Check if the method can be compiled, change level if necessary
  void compile(methodHandle mh, int bci, CompLevel level, TRAPS);
  // Submit a given method for compilation
  virtual void submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS);
  // Simple methods are as good being compiled with C1 as C2.
  // This function tells if it's such a function.
  inline bool is_trivial(methodOop method);

  // Predicate helpers are used by .*_predicate() methods as well as others.
  // They check the given counter values, multiplied by the scale against the thresholds.
  template<CompLevel level> static inline bool call_predicate_helper(int i, int b, double scale);
  template<CompLevel level> static inline bool loop_predicate_helper(int i, int b, double scale);

  // Get a compilation level for a given method.
  static CompLevel comp_level(methodOop method) {
    nmethod *nm = method->code();
    if (nm != NULL && nm->is_in_use()) {
      return (CompLevel)nm->comp_level();
    }
    return CompLevel_none;
  }
  virtual void method_invocation_event(methodHandle method, methodHandle inlinee,
                                       CompLevel level, nmethod* nm, TRAPS);
  virtual void method_back_branch_event(methodHandle method, methodHandle inlinee,
                                        int bci, CompLevel level, nmethod* nm, TRAPS);
public:
  SimpleThresholdPolicy() : _c1_count(0), _c2_count(0) { }
  virtual int compiler_count(CompLevel comp_level) {
    if (is_c1_compile(comp_level)) return c1_count();
    if (is_c2_compile(comp_level)) return c2_count();
    return 0;
  }
  virtual CompLevel initial_compile_level() { return MIN2((CompLevel)TieredStopAtLevel, CompLevel_initial_compile); }
  virtual void do_safepoint_work() { }
  virtual void delay_compilation(methodOop method) { }
  virtual void disable_compilation(methodOop method) { }
  virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
  virtual nmethod* event(methodHandle method, methodHandle inlinee,
                         int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS);
  // Select task is called by CompileBroker. We should return a task or NULL.
  virtual CompileTask* select_task(CompileQueue* compile_queue);
  // Tell the runtime if we think a given method is adequately profiled.
  virtual bool is_mature(methodOop method);
  // Initialize: set compiler thread count
  virtual void initialize();
  virtual bool should_not_inline(ciEnv* env, ciMethod* callee) {
    return (env->comp_level() == CompLevel_limited_profile ||
            env->comp_level() == CompLevel_full_profile) &&
            callee->has_loops();
  }
};

#endif // SHARE_VM_RUNTIME_SIMPLETHRESHOLDPOLICY_HPP