1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/c1/c1_ValueStack.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,285 @@ 1.4 +/* 1.5 + * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "incls/_precompiled.incl" 1.29 +#include "incls/_c1_ValueStack.cpp.incl" 1.30 + 1.31 + 1.32 +// Implementation of ValueStack 1.33 + 1.34 +ValueStack::ValueStack(IRScope* scope, int locals_size, int max_stack_size) 1.35 +: _scope(scope) 1.36 +, _locals(locals_size, NULL) 1.37 +, _stack(max_stack_size) 1.38 +, _lock_stack(false) 1.39 +, _locks(1) 1.40 +{ 1.41 + assert(scope != NULL, "scope must exist"); 1.42 +} 1.43 + 1.44 +ValueStack* ValueStack::copy() { 1.45 + ValueStack* s = new ValueStack(scope(), locals_size(), max_stack_size()); 1.46 + s->_stack.appendAll(&_stack); 1.47 + s->_locks.appendAll(&_locks); 1.48 + s->replace_locals(this); 1.49 + return s; 1.50 +} 1.51 + 1.52 + 1.53 +ValueStack* ValueStack::copy_locks() { 1.54 + int sz = scope()->lock_stack_size(); 1.55 + if (stack_size() == 0) { 1.56 + sz = 0; 1.57 + } 1.58 + ValueStack* s = new ValueStack(scope(), locals_size(), sz); 1.59 + s->_lock_stack = true; 1.60 + s->_locks.appendAll(&_locks); 1.61 + s->replace_locals(this); 1.62 + if (sz > 0) { 1.63 + assert(sz <= stack_size(), "lock stack underflow"); 1.64 + for (int i = 0; i < sz; i++) { 1.65 + s->_stack.append(_stack[i]); 1.66 + } 1.67 + } 1.68 + return s; 1.69 +} 1.70 + 1.71 +bool ValueStack::is_same(ValueStack* s) { 1.72 + assert(s != NULL, "state must exist"); 1.73 + assert(scope () == s->scope (), "scopes must correspond"); 1.74 + assert(locals_size() == s->locals_size(), "locals sizes must correspond"); 1.75 + return is_same_across_scopes(s); 1.76 +} 1.77 + 1.78 + 1.79 +bool ValueStack::is_same_across_scopes(ValueStack* s) { 1.80 + assert(s != NULL, "state must exist"); 1.81 + assert(stack_size () == s->stack_size (), "stack sizes must correspond"); 1.82 + assert(locks_size () == s->locks_size (), "locks sizes must correspond"); 1.83 + // compare each stack element with the corresponding stack element of s 1.84 + int index; 1.85 + Value value; 1.86 + for_each_stack_value(this, index, value) { 1.87 + if (value->type()->tag() != s->stack_at(index)->type()->tag()) return false; 1.88 + } 1.89 + for_each_lock_value(this, index, value) { 1.90 + if (value != s->lock_at(index)) return false; 1.91 + } 1.92 + return true; 1.93 +} 1.94 + 1.95 + 1.96 +ValueStack* ValueStack::caller_state() const { 1.97 + return scope()->caller_state(); 1.98 +} 1.99 + 1.100 + 1.101 +void ValueStack::clear_locals() { 1.102 + for (int i = _locals.length() - 1; i >= 0; i--) { 1.103 + _locals.at_put(i, NULL); 1.104 + } 1.105 +} 1.106 + 1.107 + 1.108 +void ValueStack::replace_locals(ValueStack* with) { 1.109 + assert(locals_size() == with->locals_size(), "number of locals must match"); 1.110 + for (int i = locals_size() - 1; i >= 0; i--) { 1.111 + _locals.at_put(i, with->_locals.at(i)); 1.112 + } 1.113 +} 1.114 + 1.115 +void ValueStack::pin_stack_for_linear_scan() { 1.116 + for_each_state_value(this, v, 1.117 + if (v->as_Constant() == NULL && v->as_Local() == NULL) { 1.118 + v->pin(Instruction::PinStackForStateSplit); 1.119 + } 1.120 + ); 1.121 +} 1.122 + 1.123 + 1.124 +// apply function to all values of a list; factored out from values_do(f) 1.125 +void ValueStack::apply(Values list, void f(Value*)) { 1.126 + for (int i = 0; i < list.length(); i++) { 1.127 + Value* va = list.adr_at(i); 1.128 + Value v0 = *va; 1.129 + if (v0 != NULL) { 1.130 + if (!v0->type()->is_illegal()) { 1.131 + assert(v0->as_HiWord() == NULL, "should never see HiWord during traversal"); 1.132 + f(va); 1.133 +#ifdef ASSERT 1.134 + Value v1 = *va; 1.135 + if (v0 != v1) { 1.136 + assert(v1->type()->is_illegal() || v0->type()->tag() == v1->type()->tag(), "types must match"); 1.137 + if (v0->type()->is_double_word()) { 1.138 + list.at_put(i + 1, v0->hi_word()); 1.139 + } 1.140 + } 1.141 +#endif 1.142 + if (v0->type()->is_double_word()) i++; 1.143 + } 1.144 + } 1.145 + } 1.146 +} 1.147 + 1.148 + 1.149 +void ValueStack::values_do(void f(Value*)) { 1.150 + apply(_stack, f); 1.151 + apply(_locks, f); 1.152 + 1.153 + ValueStack* state = this; 1.154 + for_each_state(state) { 1.155 + apply(state->_locals, f); 1.156 + } 1.157 +} 1.158 + 1.159 + 1.160 +Values* ValueStack::pop_arguments(int argument_size) { 1.161 + assert(stack_size() >= argument_size, "stack too small or too many arguments"); 1.162 + int base = stack_size() - argument_size; 1.163 + Values* args = new Values(argument_size); 1.164 + for (int i = base; i < stack_size();) args->push(stack_at_inc(i)); 1.165 + truncate_stack(base); 1.166 + return args; 1.167 +} 1.168 + 1.169 + 1.170 +int ValueStack::lock(IRScope* scope, Value obj) { 1.171 + _locks.push(obj); 1.172 + scope->set_min_number_of_locks(locks_size()); 1.173 + return locks_size() - 1; 1.174 +} 1.175 + 1.176 + 1.177 +int ValueStack::unlock() { 1.178 + _locks.pop(); 1.179 + return locks_size(); 1.180 +} 1.181 + 1.182 + 1.183 +ValueStack* ValueStack::push_scope(IRScope* scope) { 1.184 + assert(scope->caller() == _scope, "scopes must have caller/callee relationship"); 1.185 + ValueStack* res = new ValueStack(scope, 1.186 + scope->method()->max_locals(), 1.187 + max_stack_size() + scope->method()->max_stack()); 1.188 + // Preserves stack and monitors. 1.189 + res->_stack.appendAll(&_stack); 1.190 + res->_locks.appendAll(&_locks); 1.191 + assert(res->_stack.size() <= res->max_stack_size(), "stack overflow"); 1.192 + return res; 1.193 +} 1.194 + 1.195 + 1.196 +ValueStack* ValueStack::pop_scope() { 1.197 + assert(_scope->caller() != NULL, "scope must have caller"); 1.198 + IRScope* scope = _scope->caller(); 1.199 + int max_stack = max_stack_size() - _scope->method()->max_stack(); 1.200 + assert(max_stack >= 0, "stack underflow"); 1.201 + ValueStack* res = new ValueStack(scope, 1.202 + scope->method()->max_locals(), 1.203 + max_stack); 1.204 + // Preserves stack and monitors. Restores local and store state from caller scope. 1.205 + res->_stack.appendAll(&_stack); 1.206 + res->_locks.appendAll(&_locks); 1.207 + ValueStack* caller = caller_state(); 1.208 + if (caller != NULL) { 1.209 + for (int i = 0; i < caller->_locals.length(); i++) { 1.210 + res->_locals.at_put(i, caller->_locals.at(i)); 1.211 + } 1.212 + assert(res->_locals.length() == res->scope()->method()->max_locals(), "just checking"); 1.213 + } 1.214 + assert(res->_stack.size() <= res->max_stack_size(), "stack overflow"); 1.215 + return res; 1.216 +} 1.217 + 1.218 + 1.219 +void ValueStack::setup_phi_for_stack(BlockBegin* b, int index) { 1.220 + assert(stack_at(index)->as_Phi() == NULL || stack_at(index)->as_Phi()->block() != b, "phi function already created"); 1.221 + 1.222 + ValueType* t = stack_at(index)->type(); 1.223 + Value phi = new Phi(t, b, -index - 1); 1.224 + _stack[index] = phi; 1.225 + 1.226 +#ifdef ASSERT 1.227 + if (t->is_double_word()) { 1.228 + _stack[index + 1] = phi->hi_word(); 1.229 + } 1.230 +#endif 1.231 +} 1.232 + 1.233 +void ValueStack::setup_phi_for_local(BlockBegin* b, int index) { 1.234 + assert(local_at(index)->as_Phi() == NULL || local_at(index)->as_Phi()->block() != b, "phi function already created"); 1.235 + 1.236 + ValueType* t = local_at(index)->type(); 1.237 + Value phi = new Phi(t, b, index); 1.238 + store_local(index, phi); 1.239 +} 1.240 + 1.241 +#ifndef PRODUCT 1.242 +void ValueStack::print() { 1.243 + if (stack_is_empty()) { 1.244 + tty->print_cr("empty stack"); 1.245 + } else { 1.246 + InstructionPrinter ip; 1.247 + for (int i = 0; i < stack_size();) { 1.248 + Value t = stack_at_inc(i); 1.249 + tty->print("%2d ", i); 1.250 + ip.print_instr(t); 1.251 + tty->cr(); 1.252 + } 1.253 + } 1.254 + if (!no_active_locks()) { 1.255 + InstructionPrinter ip; 1.256 + for (int i = 0; i < locks_size(); i--) { 1.257 + Value t = lock_at(i); 1.258 + tty->print("lock %2d ", i); 1.259 + if (t == NULL) { 1.260 + tty->print("this"); 1.261 + } else { 1.262 + ip.print_instr(t); 1.263 + } 1.264 + tty->cr(); 1.265 + } 1.266 + } 1.267 + if (locals_size() > 0) { 1.268 + InstructionPrinter ip; 1.269 + for (int i = 0; i < locals_size();) { 1.270 + Value l = _locals[i]; 1.271 + tty->print("local %d ", i); 1.272 + if (l == NULL) { 1.273 + tty->print("null"); 1.274 + i ++; 1.275 + } else { 1.276 + ip.print_instr(l); 1.277 + if (l->type()->is_illegal() || l->type()->is_single_word()) i ++; else i += 2; 1.278 + } 1.279 + tty->cr(); 1.280 + } 1.281 + } 1.282 +} 1.283 + 1.284 + 1.285 +void ValueStack::verify() { 1.286 + Unimplemented(); 1.287 +} 1.288 +#endif // PRODUCT