hotspot/src/share/vm/c1/c1_ValueStack.hpp
changeset 6745 a34ef8968a84
parent 5707 6c66849ed24e
child 6748 5084ee905ab5
equal deleted inserted replaced
6743:ef1795cd50a7 6745:a34ef8968a84
    21  * questions.
    21  * questions.
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 class ValueStack: public CompilationResourceObj {
    25 class ValueStack: public CompilationResourceObj {
       
    26  public:
       
    27   enum Kind {
       
    28     Parsing,             // During abstract interpretation in GraphBuilder
       
    29     CallerState,         // Caller state when inlining
       
    30     StateBefore,         // Before before execution of instruction
       
    31     StateAfter,          // After execution of instruction
       
    32     ExceptionState,      // Exception handling of instruction
       
    33     EmptyExceptionState, // Exception handling of instructions not covered by an xhandler
       
    34     BlockBeginState      // State of BlockBegin instruction with phi functions of this block
       
    35   };
       
    36 
    26  private:
    37  private:
    27   IRScope* _scope;                               // the enclosing scope
    38   IRScope* _scope;                               // the enclosing scope
    28   bool     _lock_stack;                          // indicates that this ValueStack is for an exception site
    39   ValueStack* _caller_state;
       
    40   int      _bci;
       
    41   Kind     _kind;
       
    42 
    29   Values   _locals;                              // the locals
    43   Values   _locals;                              // the locals
    30   Values   _stack;                               // the expression stack
    44   Values   _stack;                               // the expression stack
    31   Values   _locks;                               // the monitor stack (holding the locked values)
    45   Values   _locks;                               // the monitor stack (holding the locked values)
    32 
    46 
    33   Value check(ValueTag tag, Value t) {
    47   Value check(ValueTag tag, Value t) {
    34     assert(tag == t->type()->tag() || tag == objectTag && t->type()->tag() == addressTag, "types must correspond");
    48     assert(tag == t->type()->tag() || tag == objectTag && t->type()->tag() == addressTag, "types must correspond");
    35     return t;
    49     return t;
    36   }
    50   }
    37 
    51 
    38   Value check(ValueTag tag, Value t, Value h) {
    52   Value check(ValueTag tag, Value t, Value h) {
    39     assert(h->as_HiWord()->lo_word() == t, "incorrect stack pair");
    53     assert(h == NULL, "hi-word of doubleword value must be NULL");
    40     return check(tag, t);
    54     return check(tag, t);
    41   }
    55   }
    42 
    56 
    43   // helper routine
    57   // helper routine
    44   static void apply(Values list, ValueVisitor* f);
    58   static void apply(Values list, ValueVisitor* f);
    45 
    59 
       
    60   // for simplified copying
       
    61   ValueStack(ValueStack* copy_from, Kind kind, int bci);
       
    62 
    46  public:
    63  public:
    47   // creation
    64   // creation
    48   ValueStack(IRScope* scope, int locals_size, int max_stack_size);
    65   ValueStack(IRScope* scope, ValueStack* caller_state);
    49 
    66 
    50   // merging
    67   ValueStack* copy()                             { return new ValueStack(this, _kind, _bci); }
    51   ValueStack* copy();                            // returns a copy of this w/ cleared locals
    68   ValueStack* copy(Kind new_kind, int new_bci)   { return new ValueStack(this, new_kind, new_bci); }
    52   ValueStack* copy_locks();                      // returns a copy of this w/ cleared locals and stack
    69   ValueStack* copy_for_parsing()                 { return new ValueStack(this, Parsing, -99); }
    53                                                  // Note that when inlining of methods with exception
    70 
    54                                                  // handlers is enabled, this stack may have a
    71   void set_caller_state(ValueStack* s)           { assert(kind() == EmptyExceptionState, "only EmptyExceptionStates can be modified"); _caller_state = s; }
    55                                                  // non-empty expression stack (size defined by
    72 
    56                                                  // scope()->lock_stack_size())
       
    57   bool is_same(ValueStack* s);                   // returns true if this & s's types match (w/o checking locals)
    73   bool is_same(ValueStack* s);                   // returns true if this & s's types match (w/o checking locals)
    58   bool is_same_across_scopes(ValueStack* s);     // same as is_same but returns true even if stacks are in different scopes (used for block merging w/inlining)
       
    59 
    74 
    60   // accessors
    75   // accessors
    61   IRScope* scope() const                         { return _scope; }
    76   IRScope* scope() const                         { return _scope; }
    62   bool is_lock_stack() const                     { return _lock_stack; }
    77   ValueStack* caller_state() const               { return _caller_state; }
       
    78   int bci() const                                { return _bci; }
       
    79   Kind kind() const                              { return _kind; }
       
    80 
    63   int locals_size() const                        { return _locals.length(); }
    81   int locals_size() const                        { return _locals.length(); }
    64   int stack_size() const                         { return _stack.length(); }
    82   int stack_size() const                         { return _stack.length(); }
    65   int locks_size() const                         { return _locks.length(); }
    83   int locks_size() const                         { return _locks.length(); }
    66   int max_stack_size() const                     { return _stack.capacity(); }
       
    67   bool stack_is_empty() const                    { return _stack.is_empty(); }
    84   bool stack_is_empty() const                    { return _stack.is_empty(); }
    68   bool no_active_locks() const                   { return _locks.is_empty(); }
    85   bool no_active_locks() const                   { return _locks.is_empty(); }
    69   ValueStack* caller_state() const;
    86   int total_locks_size() const;
    70 
    87 
    71   // locals access
    88   // locals access
    72   void clear_locals();                           // sets all locals to NULL;
    89   void clear_locals();                           // sets all locals to NULL;
    73 
    90 
    74   // Kill local i.  Also kill local i+1 if i was a long or double.
       
    75   void invalidate_local(int i) {
    91   void invalidate_local(int i) {
       
    92     assert(_locals.at(i)->type()->is_single_word() ||
       
    93            _locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL");
       
    94     _locals.at_put(i, NULL);
       
    95   }
       
    96 
       
    97   Value local_at(int i) const {
    76     Value x = _locals.at(i);
    98     Value x = _locals.at(i);
    77     if (x != NULL && x->type()->is_double_word()) {
    99     assert(x == NULL || x->type()->is_single_word() ||
    78       assert(_locals.at(i + 1)->as_HiWord()->lo_word() == x, "locals inconsistent");
   100            _locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL");
    79       _locals.at_put(i + 1, NULL);
       
    80     }
       
    81     _locals.at_put(i, NULL);
       
    82   }
       
    83 
       
    84 
       
    85   Value load_local(int i) const {
       
    86     Value x = _locals.at(i);
       
    87     if (x != NULL && x->type()->is_illegal()) return NULL;
       
    88     assert(x == NULL || x->as_HiWord() == NULL, "index points to hi word");
       
    89     assert(x == NULL || x->type()->is_illegal() || x->type()->is_single_word() || x == _locals.at(i+1)->as_HiWord()->lo_word(), "locals inconsistent");
       
    90     return x;
   101     return x;
    91   }
   102   }
    92 
   103 
    93   Value local_at(int i) const { return _locals.at(i); }
       
    94 
       
    95   // Store x into local i.
       
    96   void store_local(int i, Value x) {
   104   void store_local(int i, Value x) {
    97     // Kill the old value
   105     // When overwriting local i, check if i - 1 was the start of a
    98     invalidate_local(i);
   106     // double word local and kill it.
    99     _locals.at_put(i, x);
       
   100 
       
   101     // Writing a double word can kill other locals
       
   102     if (x != NULL && x->type()->is_double_word()) {
       
   103       // If x + i was the start of a double word local then kill i + 2.
       
   104       Value x2 = _locals.at(i + 1);
       
   105       if (x2 != NULL && x2->type()->is_double_word()) {
       
   106         _locals.at_put(i + 2, NULL);
       
   107       }
       
   108 
       
   109       // If x is a double word local, also update i + 1.
       
   110 #ifdef ASSERT
       
   111       _locals.at_put(i + 1, x->hi_word());
       
   112 #else
       
   113       _locals.at_put(i + 1, NULL);
       
   114 #endif
       
   115     }
       
   116     // If x - 1 was the start of a double word local then kill i - 1.
       
   117     if (i > 0) {
   107     if (i > 0) {
   118       Value prev = _locals.at(i - 1);
   108       Value prev = _locals.at(i - 1);
   119       if (prev != NULL && prev->type()->is_double_word()) {
   109       if (prev != NULL && prev->type()->is_double_word()) {
   120         _locals.at_put(i - 1, NULL);
   110         _locals.at_put(i - 1, NULL);
   121       }
   111       }
   122     }
   112     }
   123   }
   113 
   124 
   114     _locals.at_put(i, x);
   125   void replace_locals(ValueStack* with);
   115     if (x->type()->is_double_word()) {
       
   116       // hi-word of doubleword value is always NULL
       
   117       _locals.at_put(i + 1, NULL);
       
   118     }
       
   119   }
   126 
   120 
   127   // stack access
   121   // stack access
   128   Value stack_at(int i) const {
   122   Value stack_at(int i) const {
   129     Value x = _stack.at(i);
   123     Value x = _stack.at(i);
   130     assert(x->as_HiWord() == NULL, "index points to hi word");
       
   131     assert(x->type()->is_single_word() ||
   124     assert(x->type()->is_single_word() ||
   132            x->subst() == _stack.at(i+1)->as_HiWord()->lo_word(), "stack inconsistent");
   125            _stack.at(i + 1) == NULL, "hi-word of doubleword value must be NULL");
   133     return x;
   126     return x;
   134   }
   127   }
   135 
   128 
   136   Value stack_at_inc(int& i) const {
   129   Value stack_at_inc(int& i) const {
   137     Value x = stack_at(i);
   130     Value x = stack_at(i);
   144 
   137 
   145   // iteration
   138   // iteration
   146   void values_do(ValueVisitor* f);
   139   void values_do(ValueVisitor* f);
   147 
   140 
   148   // untyped manipulation (for dup_x1, etc.)
   141   // untyped manipulation (for dup_x1, etc.)
   149   void clear_stack()                             { _stack.clear(); }
       
   150   void truncate_stack(int size)                  { _stack.trunc_to(size); }
   142   void truncate_stack(int size)                  { _stack.trunc_to(size); }
   151   void raw_push(Value t)                         { _stack.push(t); }
   143   void raw_push(Value t)                         { _stack.push(t); }
   152   Value raw_pop()                                { return _stack.pop(); }
   144   Value raw_pop()                                { return _stack.pop(); }
   153 
   145 
   154   // typed manipulation
   146   // typed manipulation
   155   void ipush(Value t)                            { _stack.push(check(intTag    , t)); }
   147   void ipush(Value t)                            { _stack.push(check(intTag    , t)); }
   156   void fpush(Value t)                            { _stack.push(check(floatTag  , t)); }
   148   void fpush(Value t)                            { _stack.push(check(floatTag  , t)); }
   157   void apush(Value t)                            { _stack.push(check(objectTag , t)); }
   149   void apush(Value t)                            { _stack.push(check(objectTag , t)); }
   158   void rpush(Value t)                            { _stack.push(check(addressTag, t)); }
   150   void rpush(Value t)                            { _stack.push(check(addressTag, t)); }
   159 #ifdef ASSERT
       
   160   // in debug mode, use HiWord for 2-word values
       
   161   void lpush(Value t)                            { _stack.push(check(longTag   , t)); _stack.push(new HiWord(t)); }
       
   162   void dpush(Value t)                            { _stack.push(check(doubleTag , t)); _stack.push(new HiWord(t)); }
       
   163 #else
       
   164   // in optimized mode, use NULL for 2-word values
       
   165   void lpush(Value t)                            { _stack.push(check(longTag   , t)); _stack.push(NULL); }
   151   void lpush(Value t)                            { _stack.push(check(longTag   , t)); _stack.push(NULL); }
   166   void dpush(Value t)                            { _stack.push(check(doubleTag , t)); _stack.push(NULL); }
   152   void dpush(Value t)                            { _stack.push(check(doubleTag , t)); _stack.push(NULL); }
   167 #endif // ASSERT
       
   168 
   153 
   169   void push(ValueType* type, Value t) {
   154   void push(ValueType* type, Value t) {
   170     switch (type->tag()) {
   155     switch (type->tag()) {
   171       case intTag    : ipush(t); return;
   156       case intTag    : ipush(t); return;
   172       case longTag   : lpush(t); return;
   157       case longTag   : lpush(t); return;
   180 
   165 
   181   Value ipop()                                   { return check(intTag    , _stack.pop()); }
   166   Value ipop()                                   { return check(intTag    , _stack.pop()); }
   182   Value fpop()                                   { return check(floatTag  , _stack.pop()); }
   167   Value fpop()                                   { return check(floatTag  , _stack.pop()); }
   183   Value apop()                                   { return check(objectTag , _stack.pop()); }
   168   Value apop()                                   { return check(objectTag , _stack.pop()); }
   184   Value rpop()                                   { return check(addressTag, _stack.pop()); }
   169   Value rpop()                                   { return check(addressTag, _stack.pop()); }
   185 #ifdef ASSERT
       
   186   // in debug mode, check for HiWord consistency
       
   187   Value lpop()                                   { Value h = _stack.pop(); return check(longTag  , _stack.pop(), h); }
   170   Value lpop()                                   { Value h = _stack.pop(); return check(longTag  , _stack.pop(), h); }
   188   Value dpop()                                   { Value h = _stack.pop(); return check(doubleTag, _stack.pop(), h); }
   171   Value dpop()                                   { Value h = _stack.pop(); return check(doubleTag, _stack.pop(), h); }
   189 #else
       
   190   // in optimized mode, ignore HiWord since it is NULL
       
   191   Value lpop()                                   { _stack.pop(); return check(longTag  , _stack.pop()); }
       
   192   Value dpop()                                   { _stack.pop(); return check(doubleTag, _stack.pop()); }
       
   193 #endif // ASSERT
       
   194 
   172 
   195   Value pop(ValueType* type) {
   173   Value pop(ValueType* type) {
   196     switch (type->tag()) {
   174     switch (type->tag()) {
   197       case intTag    : return ipop();
   175       case intTag    : return ipop();
   198       case longTag   : return lpop();
   176       case longTag   : return lpop();
   206   }
   184   }
   207 
   185 
   208   Values* pop_arguments(int argument_size);
   186   Values* pop_arguments(int argument_size);
   209 
   187 
   210   // locks access
   188   // locks access
   211   int lock  (IRScope* scope, Value obj);
   189   int lock  (Value obj);
   212   int unlock();
   190   int unlock();
   213   Value lock_at(int i) const                     { return _locks.at(i); }
   191   Value lock_at(int i) const                     { return _locks.at(i); }
   214 
       
   215   // Inlining support
       
   216   ValueStack* push_scope(IRScope* scope);         // "Push" new scope, returning new resulting stack
       
   217                                                   // Preserves stack and locks, destroys locals
       
   218   ValueStack* pop_scope();                        // "Pop" topmost scope, returning new resulting stack
       
   219                                                   // Preserves stack and locks, destroys locals
       
   220 
   192 
   221   // SSA form IR support
   193   // SSA form IR support
   222   void setup_phi_for_stack(BlockBegin* b, int index);
   194   void setup_phi_for_stack(BlockBegin* b, int index);
   223   void setup_phi_for_local(BlockBegin* b, int index);
   195   void setup_phi_for_local(BlockBegin* b, int index);
   224 
   196 
   296 
   268 
   297 #define for_each_state_value(v_state, v_value, v_code)                                         \
   269 #define for_each_state_value(v_state, v_value, v_code)                                         \
   298 {                                                                                              \
   270 {                                                                                              \
   299   int cur_index;                                                                               \
   271   int cur_index;                                                                               \
   300   ValueStack* cur_state = v_state;                                                             \
   272   ValueStack* cur_state = v_state;                                                             \
   301   Value v_value;                                                                                 \
   273   Value v_value;                                                                               \
   302   {                                                                                            \
   274   for_each_state(cur_state) {                                                                  \
   303     for_each_stack_value(cur_state, cur_index, v_value) {                                      \
   275     {                                                                                            \
   304       v_code;                                                                                  \
   276       for_each_local_value(cur_state, cur_index, v_value) {                                      \
       
   277         v_code;                                                                                  \
       
   278       }                                                                                          \
   305     }                                                                                          \
   279     }                                                                                          \
   306   }                                                                                            \
   280     {                                                                                            \
   307   for_each_state(cur_state) {                                                                  \
   281       for_each_stack_value(cur_state, cur_index, v_value) {                                      \
   308     for_each_local_value(cur_state, cur_index, v_value) {                                      \
   282         v_code;                                                                                  \
   309       v_code;                                                                                  \
   283       }                                                                                          \
   310     }                                                                                          \
   284     }                                                                                            \
   311   }                                                                                            \
   285   }                                                                                            \
   312 }
   286 }
   313 
   287 
   314 
   288 
   315 // Macro definition for simple iteration of all phif functions of a block, i.e all
   289 // Macro definition for simple iteration of all phif functions of a block, i.e all