src/share/vm/c1/c1_ValueStack.hpp

changeset 2174
f02a8bbe6ed4
parent 1939
b812ff5abc73
child 2177
1375bc8922e4
     1.1 --- a/src/share/vm/c1/c1_ValueStack.hpp	Wed Sep 22 23:51:03 2010 -0700
     1.2 +++ b/src/share/vm/c1/c1_ValueStack.hpp	Tue Dec 29 19:08:54 2009 +0100
     1.3 @@ -23,9 +23,23 @@
     1.4   */
     1.5  
     1.6  class ValueStack: public CompilationResourceObj {
     1.7 + public:
     1.8 +  enum Kind {
     1.9 +    Parsing,             // During abstract interpretation in GraphBuilder
    1.10 +    CallerState,         // Caller state when inlining
    1.11 +    StateBefore,         // Before before execution of instruction
    1.12 +    StateAfter,          // After execution of instruction
    1.13 +    ExceptionState,      // Exception handling of instruction
    1.14 +    EmptyExceptionState, // Exception handling of instructions not covered by an xhandler
    1.15 +    BlockBeginState      // State of BlockBegin instruction with phi functions of this block
    1.16 +  };
    1.17 +
    1.18   private:
    1.19    IRScope* _scope;                               // the enclosing scope
    1.20 -  bool     _lock_stack;                          // indicates that this ValueStack is for an exception site
    1.21 +  ValueStack* _caller_state;
    1.22 +  int      _bci;
    1.23 +  Kind     _kind;
    1.24 +
    1.25    Values   _locals;                              // the locals
    1.26    Values   _stack;                               // the expression stack
    1.27    Values   _locks;                               // the monitor stack (holding the locked values)
    1.28 @@ -36,100 +50,79 @@
    1.29    }
    1.30  
    1.31    Value check(ValueTag tag, Value t, Value h) {
    1.32 -    assert(h->as_HiWord()->lo_word() == t, "incorrect stack pair");
    1.33 +    assert(h == NULL, "hi-word of doubleword value must be NULL");
    1.34      return check(tag, t);
    1.35    }
    1.36  
    1.37    // helper routine
    1.38    static void apply(Values list, ValueVisitor* f);
    1.39  
    1.40 +  // for simplified copying
    1.41 +  ValueStack(ValueStack* copy_from, Kind kind, int bci);
    1.42 +
    1.43   public:
    1.44    // creation
    1.45 -  ValueStack(IRScope* scope, int locals_size, int max_stack_size);
    1.46 +  ValueStack(IRScope* scope, ValueStack* caller_state);
    1.47  
    1.48 -  // merging
    1.49 -  ValueStack* copy();                            // returns a copy of this w/ cleared locals
    1.50 -  ValueStack* copy_locks();                      // returns a copy of this w/ cleared locals and stack
    1.51 -                                                 // Note that when inlining of methods with exception
    1.52 -                                                 // handlers is enabled, this stack may have a
    1.53 -                                                 // non-empty expression stack (size defined by
    1.54 -                                                 // scope()->lock_stack_size())
    1.55 +  ValueStack* copy()                             { return new ValueStack(this, _kind, _bci); }
    1.56 +  ValueStack* copy(Kind new_kind, int new_bci)   { return new ValueStack(this, new_kind, new_bci); }
    1.57 +  ValueStack* copy_for_parsing()                 { return new ValueStack(this, Parsing, -99); }
    1.58 +
    1.59 +  void set_caller_state(ValueStack* s)           { assert(kind() == EmptyExceptionState, "only EmptyExceptionStates can be modified"); _caller_state = s; }
    1.60 +
    1.61    bool is_same(ValueStack* s);                   // returns true if this & s's types match (w/o checking locals)
    1.62 -  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)
    1.63  
    1.64    // accessors
    1.65    IRScope* scope() const                         { return _scope; }
    1.66 -  bool is_lock_stack() const                     { return _lock_stack; }
    1.67 +  ValueStack* caller_state() const               { return _caller_state; }
    1.68 +  int bci() const                                { return _bci; }
    1.69 +  Kind kind() const                              { return _kind; }
    1.70 +
    1.71    int locals_size() const                        { return _locals.length(); }
    1.72    int stack_size() const                         { return _stack.length(); }
    1.73    int locks_size() const                         { return _locks.length(); }
    1.74 -  int max_stack_size() const                     { return _stack.capacity(); }
    1.75    bool stack_is_empty() const                    { return _stack.is_empty(); }
    1.76    bool no_active_locks() const                   { return _locks.is_empty(); }
    1.77 -  ValueStack* caller_state() const;
    1.78 +  int total_locks_size() const;
    1.79  
    1.80    // locals access
    1.81    void clear_locals();                           // sets all locals to NULL;
    1.82  
    1.83 -  // Kill local i.  Also kill local i+1 if i was a long or double.
    1.84    void invalidate_local(int i) {
    1.85 -    Value x = _locals.at(i);
    1.86 -    if (x != NULL && x->type()->is_double_word()) {
    1.87 -      assert(_locals.at(i + 1)->as_HiWord()->lo_word() == x, "locals inconsistent");
    1.88 -      _locals.at_put(i + 1, NULL);
    1.89 -    }
    1.90 +    assert(_locals.at(i)->type()->is_single_word() ||
    1.91 +           _locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL");
    1.92      _locals.at_put(i, NULL);
    1.93    }
    1.94  
    1.95 -
    1.96 -  Value load_local(int i) const {
    1.97 +  Value local_at(int i) const {
    1.98      Value x = _locals.at(i);
    1.99 -    if (x != NULL && x->type()->is_illegal()) return NULL;
   1.100 -    assert(x == NULL || x->as_HiWord() == NULL, "index points to hi word");
   1.101 -    assert(x == NULL || x->type()->is_illegal() || x->type()->is_single_word() || x == _locals.at(i+1)->as_HiWord()->lo_word(), "locals inconsistent");
   1.102 +    assert(x == NULL || x->type()->is_single_word() ||
   1.103 +           _locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL");
   1.104      return x;
   1.105    }
   1.106  
   1.107 -  Value local_at(int i) const { return _locals.at(i); }
   1.108 -
   1.109 -  // Store x into local i.
   1.110    void store_local(int i, Value x) {
   1.111 -    // Kill the old value
   1.112 -    invalidate_local(i);
   1.113 -    _locals.at_put(i, x);
   1.114 -
   1.115 -    // Writing a double word can kill other locals
   1.116 -    if (x != NULL && x->type()->is_double_word()) {
   1.117 -      // If x + i was the start of a double word local then kill i + 2.
   1.118 -      Value x2 = _locals.at(i + 1);
   1.119 -      if (x2 != NULL && x2->type()->is_double_word()) {
   1.120 -        _locals.at_put(i + 2, NULL);
   1.121 -      }
   1.122 -
   1.123 -      // If x is a double word local, also update i + 1.
   1.124 -#ifdef ASSERT
   1.125 -      _locals.at_put(i + 1, x->hi_word());
   1.126 -#else
   1.127 -      _locals.at_put(i + 1, NULL);
   1.128 -#endif
   1.129 -    }
   1.130 -    // If x - 1 was the start of a double word local then kill i - 1.
   1.131 +    // When overwriting local i, check if i - 1 was the start of a
   1.132 +    // double word local and kill it.
   1.133      if (i > 0) {
   1.134        Value prev = _locals.at(i - 1);
   1.135        if (prev != NULL && prev->type()->is_double_word()) {
   1.136          _locals.at_put(i - 1, NULL);
   1.137        }
   1.138      }
   1.139 +
   1.140 +    _locals.at_put(i, x);
   1.141 +    if (x->type()->is_double_word()) {
   1.142 +      // hi-word of doubleword value is always NULL
   1.143 +      _locals.at_put(i + 1, NULL);
   1.144 +    }
   1.145    }
   1.146  
   1.147 -  void replace_locals(ValueStack* with);
   1.148 -
   1.149    // stack access
   1.150    Value stack_at(int i) const {
   1.151      Value x = _stack.at(i);
   1.152 -    assert(x->as_HiWord() == NULL, "index points to hi word");
   1.153      assert(x->type()->is_single_word() ||
   1.154 -           x->subst() == _stack.at(i+1)->as_HiWord()->lo_word(), "stack inconsistent");
   1.155 +           _stack.at(i + 1) == NULL, "hi-word of doubleword value must be NULL");
   1.156      return x;
   1.157    }
   1.158  
   1.159 @@ -146,7 +139,6 @@
   1.160    void values_do(ValueVisitor* f);
   1.161  
   1.162    // untyped manipulation (for dup_x1, etc.)
   1.163 -  void clear_stack()                             { _stack.clear(); }
   1.164    void truncate_stack(int size)                  { _stack.trunc_to(size); }
   1.165    void raw_push(Value t)                         { _stack.push(t); }
   1.166    Value raw_pop()                                { return _stack.pop(); }
   1.167 @@ -156,15 +148,8 @@
   1.168    void fpush(Value t)                            { _stack.push(check(floatTag  , t)); }
   1.169    void apush(Value t)                            { _stack.push(check(objectTag , t)); }
   1.170    void rpush(Value t)                            { _stack.push(check(addressTag, t)); }
   1.171 -#ifdef ASSERT
   1.172 -  // in debug mode, use HiWord for 2-word values
   1.173 -  void lpush(Value t)                            { _stack.push(check(longTag   , t)); _stack.push(new HiWord(t)); }
   1.174 -  void dpush(Value t)                            { _stack.push(check(doubleTag , t)); _stack.push(new HiWord(t)); }
   1.175 -#else
   1.176 -  // in optimized mode, use NULL for 2-word values
   1.177    void lpush(Value t)                            { _stack.push(check(longTag   , t)); _stack.push(NULL); }
   1.178    void dpush(Value t)                            { _stack.push(check(doubleTag , t)); _stack.push(NULL); }
   1.179 -#endif // ASSERT
   1.180  
   1.181    void push(ValueType* type, Value t) {
   1.182      switch (type->tag()) {
   1.183 @@ -182,15 +167,8 @@
   1.184    Value fpop()                                   { return check(floatTag  , _stack.pop()); }
   1.185    Value apop()                                   { return check(objectTag , _stack.pop()); }
   1.186    Value rpop()                                   { return check(addressTag, _stack.pop()); }
   1.187 -#ifdef ASSERT
   1.188 -  // in debug mode, check for HiWord consistency
   1.189    Value lpop()                                   { Value h = _stack.pop(); return check(longTag  , _stack.pop(), h); }
   1.190    Value dpop()                                   { Value h = _stack.pop(); return check(doubleTag, _stack.pop(), h); }
   1.191 -#else
   1.192 -  // in optimized mode, ignore HiWord since it is NULL
   1.193 -  Value lpop()                                   { _stack.pop(); return check(longTag  , _stack.pop()); }
   1.194 -  Value dpop()                                   { _stack.pop(); return check(doubleTag, _stack.pop()); }
   1.195 -#endif // ASSERT
   1.196  
   1.197    Value pop(ValueType* type) {
   1.198      switch (type->tag()) {
   1.199 @@ -208,16 +186,10 @@
   1.200    Values* pop_arguments(int argument_size);
   1.201  
   1.202    // locks access
   1.203 -  int lock  (IRScope* scope, Value obj);
   1.204 +  int lock  (Value obj);
   1.205    int unlock();
   1.206    Value lock_at(int i) const                     { return _locks.at(i); }
   1.207  
   1.208 -  // Inlining support
   1.209 -  ValueStack* push_scope(IRScope* scope);         // "Push" new scope, returning new resulting stack
   1.210 -                                                  // Preserves stack and locks, destroys locals
   1.211 -  ValueStack* pop_scope();                        // "Pop" topmost scope, returning new resulting stack
   1.212 -                                                  // Preserves stack and locks, destroys locals
   1.213 -
   1.214    // SSA form IR support
   1.215    void setup_phi_for_stack(BlockBegin* b, int index);
   1.216    void setup_phi_for_local(BlockBegin* b, int index);
   1.217 @@ -298,16 +270,18 @@
   1.218  {                                                                                              \
   1.219    int cur_index;                                                                               \
   1.220    ValueStack* cur_state = v_state;                                                             \
   1.221 -  Value v_value;                                                                                 \
   1.222 -  {                                                                                            \
   1.223 -    for_each_stack_value(cur_state, cur_index, v_value) {                                      \
   1.224 -      v_code;                                                                                  \
   1.225 +  Value v_value;                                                                               \
   1.226 +  for_each_state(cur_state) {                                                                  \
   1.227 +    {                                                                                            \
   1.228 +      for_each_local_value(cur_state, cur_index, v_value) {                                      \
   1.229 +        v_code;                                                                                  \
   1.230 +      }                                                                                          \
   1.231      }                                                                                          \
   1.232 -  }                                                                                            \
   1.233 -  for_each_state(cur_state) {                                                                  \
   1.234 -    for_each_local_value(cur_state, cur_index, v_value) {                                      \
   1.235 -      v_code;                                                                                  \
   1.236 -    }                                                                                          \
   1.237 +    {                                                                                            \
   1.238 +      for_each_stack_value(cur_state, cur_index, v_value) {                                      \
   1.239 +        v_code;                                                                                  \
   1.240 +      }                                                                                          \
   1.241 +    }                                                                                            \
   1.242    }                                                                                            \
   1.243  }
   1.244  

mercurial