diff src/share/vm/c1/c1_ValueStack.cpp @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/c1/c1_ValueStack.cpp	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,285 @@
+/*
+ * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_c1_ValueStack.cpp.incl"
+
+
+// Implementation of ValueStack
+
+ValueStack::ValueStack(IRScope* scope, int locals_size, int max_stack_size)
+: _scope(scope)
+, _locals(locals_size, NULL)
+, _stack(max_stack_size)
+, _lock_stack(false)
+, _locks(1)
+{
+  assert(scope != NULL, "scope must exist");
+}
+
+ValueStack* ValueStack::copy() {
+  ValueStack* s = new ValueStack(scope(), locals_size(), max_stack_size());
+  s->_stack.appendAll(&_stack);
+  s->_locks.appendAll(&_locks);
+  s->replace_locals(this);
+  return s;
+}
+
+
+ValueStack* ValueStack::copy_locks() {
+  int sz = scope()->lock_stack_size();
+  if (stack_size() == 0) {
+    sz = 0;
+  }
+  ValueStack* s = new ValueStack(scope(), locals_size(), sz);
+  s->_lock_stack = true;
+  s->_locks.appendAll(&_locks);
+  s->replace_locals(this);
+  if (sz > 0) {
+    assert(sz <= stack_size(), "lock stack underflow");
+    for (int i = 0; i < sz; i++) {
+      s->_stack.append(_stack[i]);
+    }
+  }
+  return s;
+}
+
+bool ValueStack::is_same(ValueStack* s) {
+  assert(s != NULL, "state must exist");
+  assert(scope      () == s->scope      (), "scopes       must correspond");
+  assert(locals_size() == s->locals_size(), "locals sizes must correspond");
+  return is_same_across_scopes(s);
+}
+
+
+bool ValueStack::is_same_across_scopes(ValueStack* s) {
+  assert(s != NULL, "state must exist");
+  assert(stack_size () == s->stack_size (), "stack  sizes must correspond");
+  assert(locks_size () == s->locks_size (), "locks  sizes must correspond");
+  // compare each stack element with the corresponding stack element of s
+  int index;
+  Value value;
+  for_each_stack_value(this, index, value) {
+    if (value->type()->tag() != s->stack_at(index)->type()->tag()) return false;
+  }
+  for_each_lock_value(this, index, value) {
+    if (value != s->lock_at(index)) return false;
+  }
+  return true;
+}
+
+
+ValueStack* ValueStack::caller_state() const {
+  return scope()->caller_state();
+}
+
+
+void ValueStack::clear_locals() {
+  for (int i = _locals.length() - 1; i >= 0; i--) {
+    _locals.at_put(i, NULL);
+  }
+}
+
+
+void ValueStack::replace_locals(ValueStack* with) {
+  assert(locals_size() == with->locals_size(), "number of locals must match");
+  for (int i = locals_size() - 1; i >= 0; i--) {
+    _locals.at_put(i, with->_locals.at(i));
+  }
+}
+
+void ValueStack::pin_stack_for_linear_scan() {
+  for_each_state_value(this, v,
+    if (v->as_Constant() == NULL && v->as_Local() == NULL) {
+      v->pin(Instruction::PinStackForStateSplit);
+    }
+  );
+}
+
+
+// apply function to all values of a list; factored out from values_do(f)
+void ValueStack::apply(Values list, void f(Value*)) {
+  for (int i = 0; i < list.length(); i++) {
+    Value* va = list.adr_at(i);
+    Value v0 = *va;
+    if (v0 != NULL) {
+      if (!v0->type()->is_illegal()) {
+        assert(v0->as_HiWord() == NULL, "should never see HiWord during traversal");
+        f(va);
+#ifdef ASSERT
+        Value v1 = *va;
+        if (v0 != v1) {
+          assert(v1->type()->is_illegal() || v0->type()->tag() == v1->type()->tag(), "types must match");
+          if (v0->type()->is_double_word()) {
+            list.at_put(i + 1, v0->hi_word());
+          }
+        }
+#endif
+        if (v0->type()->is_double_word()) i++;
+      }
+    }
+  }
+}
+
+
+void ValueStack::values_do(void f(Value*)) {
+  apply(_stack, f);
+  apply(_locks, f);
+
+  ValueStack* state = this;
+  for_each_state(state) {
+    apply(state->_locals, f);
+  }
+}
+
+
+Values* ValueStack::pop_arguments(int argument_size) {
+  assert(stack_size() >= argument_size, "stack too small or too many arguments");
+  int base = stack_size() - argument_size;
+  Values* args = new Values(argument_size);
+  for (int i = base; i < stack_size();) args->push(stack_at_inc(i));
+  truncate_stack(base);
+  return args;
+}
+
+
+int ValueStack::lock(IRScope* scope, Value obj) {
+  _locks.push(obj);
+  scope->set_min_number_of_locks(locks_size());
+  return locks_size() - 1;
+}
+
+
+int ValueStack::unlock() {
+  _locks.pop();
+  return locks_size();
+}
+
+
+ValueStack* ValueStack::push_scope(IRScope* scope) {
+  assert(scope->caller() == _scope, "scopes must have caller/callee relationship");
+  ValueStack* res = new ValueStack(scope,
+                                   scope->method()->max_locals(),
+                                   max_stack_size() + scope->method()->max_stack());
+  // Preserves stack and monitors.
+  res->_stack.appendAll(&_stack);
+  res->_locks.appendAll(&_locks);
+  assert(res->_stack.size() <= res->max_stack_size(), "stack overflow");
+  return res;
+}
+
+
+ValueStack* ValueStack::pop_scope() {
+  assert(_scope->caller() != NULL, "scope must have caller");
+  IRScope* scope = _scope->caller();
+  int max_stack = max_stack_size() - _scope->method()->max_stack();
+  assert(max_stack >= 0, "stack underflow");
+  ValueStack* res = new ValueStack(scope,
+                                   scope->method()->max_locals(),
+                                   max_stack);
+  // Preserves stack and monitors. Restores local and store state from caller scope.
+  res->_stack.appendAll(&_stack);
+  res->_locks.appendAll(&_locks);
+  ValueStack* caller = caller_state();
+  if (caller != NULL) {
+    for (int i = 0; i < caller->_locals.length(); i++) {
+      res->_locals.at_put(i, caller->_locals.at(i));
+    }
+    assert(res->_locals.length() == res->scope()->method()->max_locals(), "just checking");
+  }
+  assert(res->_stack.size() <= res->max_stack_size(), "stack overflow");
+  return res;
+}
+
+
+void ValueStack::setup_phi_for_stack(BlockBegin* b, int index) {
+  assert(stack_at(index)->as_Phi() == NULL || stack_at(index)->as_Phi()->block() != b, "phi function already created");
+
+  ValueType* t = stack_at(index)->type();
+  Value phi = new Phi(t, b, -index - 1);
+  _stack[index] = phi;
+
+#ifdef ASSERT
+  if (t->is_double_word()) {
+    _stack[index + 1] = phi->hi_word();
+  }
+#endif
+}
+
+void ValueStack::setup_phi_for_local(BlockBegin* b, int index) {
+  assert(local_at(index)->as_Phi() == NULL || local_at(index)->as_Phi()->block() != b, "phi function already created");
+
+  ValueType* t = local_at(index)->type();
+  Value phi = new Phi(t, b, index);
+  store_local(index, phi);
+}
+
+#ifndef PRODUCT
+void ValueStack::print() {
+  if (stack_is_empty()) {
+    tty->print_cr("empty stack");
+  } else {
+    InstructionPrinter ip;
+    for (int i = 0; i < stack_size();) {
+      Value t = stack_at_inc(i);
+      tty->print("%2d  ", i);
+      ip.print_instr(t);
+      tty->cr();
+    }
+  }
+  if (!no_active_locks()) {
+    InstructionPrinter ip;
+    for (int i = 0; i < locks_size(); i--) {
+      Value t = lock_at(i);
+      tty->print("lock %2d  ", i);
+      if (t == NULL) {
+        tty->print("this");
+      } else {
+        ip.print_instr(t);
+      }
+      tty->cr();
+    }
+  }
+  if (locals_size() > 0) {
+    InstructionPrinter ip;
+    for (int i = 0; i < locals_size();) {
+      Value l = _locals[i];
+      tty->print("local %d ", i);
+      if (l == NULL) {
+        tty->print("null");
+        i ++;
+      } else {
+        ip.print_instr(l);
+        if (l->type()->is_illegal() || l->type()->is_single_word()) i ++; else i += 2;
+      }
+      tty->cr();
+    }
+  }
+}
+
+
+void ValueStack::verify() {
+  Unimplemented();
+}
+#endif // PRODUCT