src/share/vm/oops/generateOopMap.hpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2497
3582bf76420e
child 2708
1d1603768966
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

     1 /*
     2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #ifndef SHARE_VM_OOPS_GENERATEOOPMAP_HPP
    26 #define SHARE_VM_OOPS_GENERATEOOPMAP_HPP
    28 #include "interpreter/bytecodeStream.hpp"
    29 #include "memory/allocation.inline.hpp"
    30 #include "memory/universe.inline.hpp"
    31 #include "oops/methodOop.hpp"
    32 #include "oops/oopsHierarchy.hpp"
    33 #include "runtime/signature.hpp"
    35 // Forward definition
    36 class MethodOopMap;
    37 class GenerateOopMap;
    38 class BasicBlock;
    39 class CellTypeState;
    40 class StackMap;
    42 // These two should be removed. But requires som code to be cleaned up
    43 #define MAXARGSIZE      256      // This should be enough
    44 #define MAX_LOCAL_VARS  65536    // 16-bit entry
    46 typedef void (*jmpFct_t)(GenerateOopMap *c, int bcpDelta, int* data);
    49 //  RetTable
    50 //
    51 // Contains maping between jsr targets and there return addresses. One-to-many mapping
    52 //
    53 class RetTableEntry : public ResourceObj {
    54  private:
    55   static int _init_nof_jsrs;                      // Default size of jsrs list
    56   int _target_bci;                                // Target PC address of jump (bytecode index)
    57   GrowableArray<intptr_t> * _jsrs;                     // List of return addresses  (bytecode index)
    58   RetTableEntry *_next;                           // Link to next entry
    59  public:
    60    RetTableEntry(int target, RetTableEntry *next)  { _target_bci=target; _jsrs = new GrowableArray<intptr_t>(_init_nof_jsrs); _next = next;  }
    62   // Query
    63   int target_bci() const                      { return _target_bci; }
    64   int nof_jsrs() const                        { return _jsrs->length(); }
    65   int jsrs(int i) const                       { assert(i>=0 && i<nof_jsrs(), "Index out of bounds"); return _jsrs->at(i); }
    67   // Update entry
    68   void add_jsr    (int return_bci)            { _jsrs->append(return_bci); }
    69   void add_delta  (int bci, int delta);
    70   RetTableEntry * next()  const               { return _next; }
    71 };
    74 class RetTable VALUE_OBJ_CLASS_SPEC {
    75  private:
    76   RetTableEntry *_first;
    77   static int _init_nof_entries;
    79   void add_jsr(int return_bci, int target_bci);   // Adds entry to list
    80  public:
    81   RetTable()                                                  { _first = NULL; }
    82   void compute_ret_table(methodHandle method);
    83   void update_ret_table(int bci, int delta);
    84   RetTableEntry* find_jsrs_for_target(int targBci);
    85 };
    87 //
    88 // CellTypeState
    89 //
    90 class CellTypeState VALUE_OBJ_CLASS_SPEC {
    91  private:
    92   unsigned int _state;
    94   // Masks for separating the BITS and INFO portions of a CellTypeState
    95   enum { info_mask            = right_n_bits(28),
    96          bits_mask            = (int)(~info_mask) };
    98   // These constant are used for manipulating the BITS portion of a
    99   // CellTypeState
   100   enum { uninit_bit           = (int)(nth_bit(31)),
   101          ref_bit              = nth_bit(30),
   102          val_bit              = nth_bit(29),
   103          addr_bit             = nth_bit(28),
   104          live_bits_mask       = (int)(bits_mask & ~uninit_bit) };
   106   // These constants are used for manipulating the INFO portion of a
   107   // CellTypeState
   108   enum { top_info_bit         = nth_bit(27),
   109          not_bottom_info_bit  = nth_bit(26),
   110          info_data_mask       = right_n_bits(26),
   111          info_conflict        = info_mask };
   113   // Within the INFO data, these values are used to distinguish different
   114   // kinds of references.
   115   enum { ref_not_lock_bit     = nth_bit(25),  // 0 if this reference is locked as a monitor
   116          ref_slot_bit         = nth_bit(24),  // 1 if this reference is a "slot" reference,
   117                                               // 0 if it is a "line" reference.
   118          ref_data_mask        = right_n_bits(24) };
   121   // These values are used to initialize commonly used CellTypeState
   122   // constants.
   123   enum { bottom_value         = 0,
   124          uninit_value         = (int)(uninit_bit | info_conflict),
   125          ref_value            = ref_bit,
   126          ref_conflict         = ref_bit | info_conflict,
   127          val_value            = val_bit | info_conflict,
   128          addr_value           = addr_bit,
   129          addr_conflict        = addr_bit | info_conflict };
   131  public:
   133   // Since some C++ constructors generate poor code for declarations of the
   134   // form...
   135   //
   136   //   CellTypeState vector[length];
   137   //
   138   // ...we avoid making a constructor for this class.  CellTypeState values
   139   // should be constructed using one of the make_* methods:
   141   static CellTypeState make_any(int state) {
   142     CellTypeState s;
   143     s._state = state;
   144     // Causes SS10 warning.
   145     // assert(s.is_valid_state(), "check to see if CellTypeState is valid");
   146     return s;
   147   }
   149   static CellTypeState make_bottom() {
   150     return make_any(0);
   151   }
   153   static CellTypeState make_top() {
   154     return make_any(AllBits);
   155   }
   157   static CellTypeState make_addr(int bci) {
   158     assert((bci >= 0) && (bci < info_data_mask), "check to see if ret addr is valid");
   159     return make_any(addr_bit | not_bottom_info_bit | (bci & info_data_mask));
   160   }
   162   static CellTypeState make_slot_ref(int slot_num) {
   163     assert(slot_num >= 0 && slot_num < ref_data_mask, "slot out of range");
   164     return make_any(ref_bit | not_bottom_info_bit | ref_not_lock_bit | ref_slot_bit |
   165                     (slot_num & ref_data_mask));
   166   }
   168   static CellTypeState make_line_ref(int bci) {
   169     assert(bci >= 0 && bci < ref_data_mask, "line out of range");
   170     return make_any(ref_bit | not_bottom_info_bit | ref_not_lock_bit |
   171                     (bci & ref_data_mask));
   172   }
   174   static CellTypeState make_lock_ref(int bci) {
   175     assert(bci >= 0 && bci < ref_data_mask, "line out of range");
   176     return make_any(ref_bit | not_bottom_info_bit | (bci & ref_data_mask));
   177   }
   179   // Query methods:
   180   bool is_bottom() const                { return _state == 0; }
   181   bool is_live() const                  { return ((_state & live_bits_mask) != 0); }
   182   bool is_valid_state() const {
   183     // Uninitialized and value cells must contain no data in their info field:
   184     if ((can_be_uninit() || can_be_value()) && !is_info_top()) {
   185       return false;
   186     }
   187     // The top bit is only set when all info bits are set:
   188     if (is_info_top() && ((_state & info_mask) != info_mask)) {
   189       return false;
   190     }
   191     // The not_bottom_bit must be set when any other info bit is set:
   192     if (is_info_bottom() && ((_state & info_mask) != 0)) {
   193       return false;
   194     }
   195     return true;
   196   }
   198   bool is_address() const               { return ((_state & bits_mask) == addr_bit); }
   199   bool is_reference() const             { return ((_state & bits_mask) == ref_bit); }
   200   bool is_value() const                 { return ((_state & bits_mask) == val_bit); }
   201   bool is_uninit() const                { return ((_state & bits_mask) == (uint)uninit_bit); }
   203   bool can_be_address() const           { return ((_state & addr_bit) != 0); }
   204   bool can_be_reference() const         { return ((_state & ref_bit) != 0); }
   205   bool can_be_value() const             { return ((_state & val_bit) != 0); }
   206   bool can_be_uninit() const            { return ((_state & uninit_bit) != 0); }
   208   bool is_info_bottom() const           { return ((_state & not_bottom_info_bit) == 0); }
   209   bool is_info_top() const              { return ((_state & top_info_bit) != 0); }
   210   int  get_info() const {
   211     assert((!is_info_top() && !is_info_bottom()),
   212            "check to make sure top/bottom info is not used");
   213     return (_state & info_data_mask);
   214   }
   216   bool is_good_address() const          { return is_address() && !is_info_top(); }
   217   bool is_lock_reference() const {
   218     return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == ref_bit);
   219   }
   220   bool is_nonlock_reference() const {
   221     return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == (ref_bit | ref_not_lock_bit));
   222   }
   224   bool equal(CellTypeState a) const     { return _state == a._state; }
   225   bool equal_kind(CellTypeState a) const {
   226     return (_state & bits_mask) == (a._state & bits_mask);
   227   }
   229   char to_char() const;
   231   // Merge
   232   CellTypeState merge (CellTypeState cts, int slot) const;
   234   // Debugging output
   235   void print(outputStream *os);
   237   // Default values of common values
   238   static CellTypeState bottom;
   239   static CellTypeState uninit;
   240   static CellTypeState ref;
   241   static CellTypeState value;
   242   static CellTypeState refUninit;
   243   static CellTypeState varUninit;
   244   static CellTypeState top;
   245   static CellTypeState addr;
   246 };
   249 //
   250 // BasicBlockStruct
   251 //
   252 class BasicBlock: ResourceObj {
   253  private:
   254   bool            _changed;                 // Reached a fixpoint or not
   255  public:
   256   enum Constants {
   257     _dead_basic_block = -2,
   258     _unreached        = -1                  // Alive but not yet reached by analysis
   259     // >=0                                  // Alive and has a merged state
   260   };
   262   int             _bci;                     // Start of basic block
   263   int             _end_bci;                 // Bci of last instruction in basicblock
   264   int             _max_locals;              // Determines split between vars and stack
   265   int             _max_stack;               // Determines split between stack and monitors
   266   CellTypeState*  _state;                   // State (vars, stack) at entry.
   267   int             _stack_top;               // -1 indicates bottom stack value.
   268   int             _monitor_top;             // -1 indicates bottom monitor stack value.
   270   CellTypeState* vars()                     { return _state; }
   271   CellTypeState* stack()                    { return _state + _max_locals; }
   273   bool changed()                            { return _changed; }
   274   void set_changed(bool s)                  { _changed = s; }
   276   bool is_reachable() const                 { return _stack_top >= 0; }  // Analysis has reached this basicblock
   278   // All basicblocks that are unreachable are going to have a _stack_top == _dead_basic_block.
   279   // This info. is setup in a pre-parse before the real abstract interpretation starts.
   280   bool is_dead() const                      { return _stack_top == _dead_basic_block; }
   281   bool is_alive() const                     { return _stack_top != _dead_basic_block; }
   282   void mark_as_alive()                      { assert(is_dead(), "must be dead"); _stack_top = _unreached; }
   283 };
   286 //
   287 //  GenerateOopMap
   288 //
   289 // Main class used to compute the pointer-maps in a MethodOop
   290 //
   291 class GenerateOopMap VALUE_OBJ_CLASS_SPEC {
   292  protected:
   294   // _monitor_top is set to this constant to indicate that a monitor matching
   295   // problem was encountered prior to this point in control flow.
   296   enum { bad_monitors = -1 };
   298   // Main variables
   299   methodHandle _method;                     // The method we are examine
   300   RetTable     _rt;                         // Contains the return address mappings
   301   int          _max_locals;                 // Cached value of no. of locals
   302   int          _max_stack;                  // Cached value of max. stack depth
   303   int          _max_monitors;               // Cached value of max. monitor stack depth
   304   int          _has_exceptions;             // True, if exceptions exist for method
   305   bool         _got_error;                  // True, if an error occurred during interpretation.
   306   Handle       _exception;                  // Exception if got_error is true.
   307   bool         _did_rewriting;              // was bytecodes rewritten
   308   bool         _did_relocation;             // was relocation neccessary
   309   bool         _monitor_safe;               // The monitors in this method have been determined
   310                                             // to be safe.
   312   // Working Cell type state
   313   int            _state_len;                // Size of states
   314   CellTypeState *_state;                    // list of states
   315   char          *_state_vec_buf;            // Buffer used to print a readable version of a state
   316   int            _stack_top;
   317   int            _monitor_top;
   319   // Timing and statistics
   320   static elapsedTimer _total_oopmap_time;   // Holds cumulative oopmap generation time
   321   static long         _total_byte_count;    // Holds cumulative number of bytes inspected
   323   // Cell type methods
   324   void            init_state();
   325   void            make_context_uninitialized ();
   326   int             methodsig_to_effect        (Symbol* signature, bool isStatic, CellTypeState* effect);
   327   bool            merge_local_state_vectors  (CellTypeState* cts, CellTypeState* bbts);
   328   bool            merge_monitor_state_vectors(CellTypeState* cts, CellTypeState* bbts);
   329   void            copy_state                 (CellTypeState *dst, CellTypeState *src);
   330   void            merge_state_into_bb        (BasicBlock *bb);
   331   static void     merge_state                (GenerateOopMap *gom, int bcidelta, int* data);
   332   void            set_var                    (int localNo, CellTypeState cts);
   333   CellTypeState   get_var                    (int localNo);
   334   CellTypeState   pop                        ();
   335   void            push                       (CellTypeState cts);
   336   CellTypeState   monitor_pop                ();
   337   void            monitor_push               (CellTypeState cts);
   338   CellTypeState * vars                       ()                                             { return _state; }
   339   CellTypeState * stack                      ()                                             { return _state+_max_locals; }
   340   CellTypeState * monitors                   ()                                             { return _state+_max_locals+_max_stack; }
   342   void            replace_all_CTS_matches    (CellTypeState match,
   343                                               CellTypeState replace);
   344   void            print_states               (outputStream *os, CellTypeState *vector, int num);
   345   void            print_current_state        (outputStream   *os,
   346                                               BytecodeStream *itr,
   347                                               bool            detailed);
   348   void            report_monitor_mismatch    (const char *msg);
   350   // Basicblock info
   351   BasicBlock *    _basic_blocks;             // Array of basicblock info
   352   int             _gc_points;
   353   int             _bb_count;
   354   BitMap          _bb_hdr_bits;
   356   // Basicblocks methods
   357   void          initialize_bb               ();
   358   void          mark_bbheaders_and_count_gc_points();
   359   bool          is_bb_header                (int bci) const   {
   360     return _bb_hdr_bits.at(bci);
   361   }
   362   int           gc_points                   () const                          { return _gc_points; }
   363   int           bb_count                    () const                          { return _bb_count; }
   364   void          set_bbmark_bit              (int bci) {
   365     _bb_hdr_bits.at_put(bci, true);
   366   }
   367   void          clear_bbmark_bit            (int bci) {
   368     _bb_hdr_bits.at_put(bci, false);
   369   }
   370   BasicBlock *  get_basic_block_at          (int bci) const;
   371   BasicBlock *  get_basic_block_containing  (int bci) const;
   372   void          interp_bb                   (BasicBlock *bb);
   373   void          restore_state               (BasicBlock *bb);
   374   int           next_bb_start_pc            (BasicBlock *bb);
   375   void          update_basic_blocks         (int bci, int delta, int new_method_size);
   376   static void   bb_mark_fct                 (GenerateOopMap *c, int deltaBci, int *data);
   378   // Dead code detection
   379   void          mark_reachable_code();
   380   static void   reachable_basicblock        (GenerateOopMap *c, int deltaBci, int *data);
   382   // Interpretation methods (primary)
   383   void  do_interpretation                   ();
   384   void  init_basic_blocks                   ();
   385   void  setup_method_entry_state            ();
   386   void  interp_all                          ();
   388   // Interpretation methods (secondary)
   389   void  interp1                             (BytecodeStream *itr);
   390   void  do_exception_edge                   (BytecodeStream *itr);
   391   void  check_type                          (CellTypeState expected, CellTypeState actual);
   392   void  ppstore                             (CellTypeState *in,  int loc_no);
   393   void  ppload                              (CellTypeState *out, int loc_no);
   394   void  ppush1                              (CellTypeState in);
   395   void  ppush                               (CellTypeState *in);
   396   void  ppop1                               (CellTypeState out);
   397   void  ppop                                (CellTypeState *out);
   398   void  ppop_any                            (int poplen);
   399   void  pp                                  (CellTypeState *in, CellTypeState *out);
   400   void  pp_new_ref                          (CellTypeState *in, int bci);
   401   void  ppdupswap                           (int poplen, const char *out);
   402   void  do_ldc                              (int bci);
   403   void  do_astore                           (int idx);
   404   void  do_jsr                              (int delta);
   405   void  do_field                            (int is_get, int is_static, int idx, int bci);
   406   void  do_method                           (int is_static, int is_interface, int idx, int bci);
   407   void  do_multianewarray                   (int dims, int bci);
   408   void  do_monitorenter                     (int bci);
   409   void  do_monitorexit                      (int bci);
   410   void  do_return_monitor_check             ();
   411   void  do_checkcast                        ();
   412   CellTypeState *sigchar_to_effect          (char sigch, int bci, CellTypeState *out);
   413   int copy_cts                              (CellTypeState *dst, CellTypeState *src);
   415   // Error handling
   416   void  error_work                          (const char *format, va_list ap);
   417   void  report_error                        (const char *format, ...);
   418   void  verify_error                        (const char *format, ...);
   419   bool  got_error()                         { return _got_error; }
   421   // Create result set
   422   bool  _report_result;
   423   bool  _report_result_for_send;            // Unfortunatly, stackmaps for sends are special, so we need some extra
   424   BytecodeStream *_itr_send;                // variables to handle them properly.
   426   void  report_result                       ();
   428   // Initvars
   429   GrowableArray<intptr_t> * _init_vars;
   431   void  initialize_vars                     ();
   432   void  add_to_ref_init_set                 (int localNo);
   434   // Conflicts rewrite logic
   435   bool      _conflict;                      // True, if a conflict occurred during interpretation
   436   int       _nof_refval_conflicts;          // No. of conflicts that require rewrites
   437   int *     _new_var_map;
   439   void record_refval_conflict               (int varNo);
   440   void rewrite_refval_conflicts             ();
   441   void rewrite_refval_conflict              (int from, int to);
   442   bool rewrite_refval_conflict_inst         (BytecodeStream *i, int from, int to);
   443   bool rewrite_load_or_store                (BytecodeStream *i, Bytecodes::Code bc, Bytecodes::Code bc0, unsigned int varNo);
   445   void expand_current_instr                 (int bci, int ilen, int newIlen, u_char inst_buffer[]);
   446   bool is_astore                            (BytecodeStream *itr, int *index);
   447   bool is_aload                             (BytecodeStream *itr, int *index);
   449   // List of bci's where a return address is on top of the stack
   450   GrowableArray<intptr_t> *_ret_adr_tos;
   452   bool stack_top_holds_ret_addr             (int bci);
   453   void compute_ret_adr_at_TOS               ();
   454   void update_ret_adr_at_TOS                (int bci, int delta);
   456   int  binsToHold                           (int no)                      { return  ((no+(BitsPerWord-1))/BitsPerWord); }
   457   char *state_vec_to_string                 (CellTypeState* vec, int len);
   459   // Helper method. Can be used in subclasses to fx. calculate gc_points. If the current instuction
   460   // is a control transfer, then calls the jmpFct all possible destinations.
   461   void  ret_jump_targets_do                 (BytecodeStream *bcs, jmpFct_t jmpFct, int varNo,int *data);
   462   bool  jump_targets_do                     (BytecodeStream *bcs, jmpFct_t jmpFct, int *data);
   464   friend class RelocCallback;
   465  public:
   466   GenerateOopMap(methodHandle method);
   468   // Compute the map.
   469   void compute_map(TRAPS);
   470   void result_for_basicblock(int bci);    // Do a callback on fill_stackmap_for_opcodes for basicblock containing bci
   472   // Query
   473   int max_locals() const                           { return _max_locals; }
   474   methodOop method() const                         { return _method(); }
   475   methodHandle method_as_handle() const            { return _method; }
   477   bool did_rewriting()                             { return _did_rewriting; }
   478   bool did_relocation()                            { return _did_relocation; }
   480   static void print_time();
   482   // Monitor query
   483   bool monitor_safe()                              { return _monitor_safe; }
   485   // Specialization methods. Intended use:
   486   // - possible_gc_point must return true for every bci for which the stackmaps must be returned
   487   // - fill_stackmap_prolog is called just before the result is reported. The arguments tells the estimated
   488   //   number of gc points
   489   // - fill_stackmap_for_opcodes is called once for each bytecode index in order (0...code_length-1)
   490   // - fill_stackmap_epilog is called after all results has been reported. Note: Since the algorithm does not report
   491   //   stackmaps for deadcode, fewer gc_points might have been encounted than assumed during the epilog. It is the
   492   //   responsibility of the subclass to count the correct number.
   493   // - fill_init_vars are called once with the result of the init_vars computation
   494   //
   495   // All these methods are used during a call to: compute_map. Note: Non of the return results are valid
   496   // after compute_map returns, since all values are allocated as resource objects.
   497   //
   498   // All virtual method must be implemented in subclasses
   499   virtual bool allow_rewrites             () const                        { return false; }
   500   virtual bool report_results             () const                        { return true;  }
   501   virtual bool report_init_vars           () const                        { return true;  }
   502   virtual bool possible_gc_point          (BytecodeStream *bcs)           { ShouldNotReachHere(); return false; }
   503   virtual void fill_stackmap_prolog       (int nof_gc_points)             { ShouldNotReachHere(); }
   504   virtual void fill_stackmap_epilog       ()                              { ShouldNotReachHere(); }
   505   virtual void fill_stackmap_for_opcodes  (BytecodeStream *bcs,
   506                                            CellTypeState* vars,
   507                                            CellTypeState* stack,
   508                                            int stackTop)                  { ShouldNotReachHere(); }
   509   virtual void fill_init_vars             (GrowableArray<intptr_t> *init_vars) { ShouldNotReachHere();; }
   510 };
   512 //
   513 // Subclass of the GenerateOopMap Class that just do rewrites of the method, if needed.
   514 // It does not store any oopmaps.
   515 //
   516 class ResolveOopMapConflicts: public GenerateOopMap {
   517  private:
   519   bool _must_clear_locals;
   521   virtual bool report_results() const     { return false; }
   522   virtual bool report_init_vars() const   { return true;  }
   523   virtual bool allow_rewrites() const     { return true;  }
   524   virtual bool possible_gc_point          (BytecodeStream *bcs)           { return false; }
   525   virtual void fill_stackmap_prolog       (int nof_gc_points)             {}
   526   virtual void fill_stackmap_epilog       ()                              {}
   527   virtual void fill_stackmap_for_opcodes  (BytecodeStream *bcs,
   528                                            CellTypeState* vars,
   529                                            CellTypeState* stack,
   530                                            int stack_top)                 {}
   531   virtual void fill_init_vars             (GrowableArray<intptr_t> *init_vars) { _must_clear_locals = init_vars->length() > 0; }
   533 #ifndef PRODUCT
   534   // Statistics
   535   static int _nof_invocations;
   536   static int _nof_rewrites;
   537   static int _nof_relocations;
   538 #endif
   540  public:
   541   ResolveOopMapConflicts(methodHandle method) : GenerateOopMap(method) { _must_clear_locals = false; };
   543   methodHandle do_potential_rewrite(TRAPS);
   544   bool must_clear_locals() const { return _must_clear_locals; }
   545 };
   548 //
   549 // Subclass used by the compiler to generate pairing infomation
   550 //
   551 class GeneratePairingInfo: public GenerateOopMap {
   552  private:
   554   virtual bool report_results() const     { return false; }
   555   virtual bool report_init_vars() const   { return false; }
   556   virtual bool allow_rewrites() const     { return false;  }
   557   virtual bool possible_gc_point          (BytecodeStream *bcs)           { return false; }
   558   virtual void fill_stackmap_prolog       (int nof_gc_points)             {}
   559   virtual void fill_stackmap_epilog       ()                              {}
   560   virtual void fill_stackmap_for_opcodes  (BytecodeStream *bcs,
   561                                            CellTypeState* vars,
   562                                            CellTypeState* stack,
   563                                            int stack_top)                 {}
   564   virtual void fill_init_vars             (GrowableArray<intptr_t> *init_vars) {}
   565  public:
   566   GeneratePairingInfo(methodHandle method) : GenerateOopMap(method)       {};
   568   // Call compute_map(CHECK) to generate info.
   569 };
   571 #endif // SHARE_VM_OOPS_GENERATEOOPMAP_HPP

mercurial