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