c1_ValueStack.cpp 8.1 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * 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.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24 25 26 27 28 29 30
 *
 */

#include "incls/_precompiled.incl"
#include "incls/_c1_ValueStack.cpp.incl"


// Implementation of ValueStack

R
roland 已提交
31
ValueStack::ValueStack(IRScope* scope, ValueStack* caller_state)
D
duke 已提交
32
: _scope(scope)
R
roland 已提交
33 34 35 36 37 38
, _caller_state(caller_state)
, _bci(-99)
, _kind(Parsing)
, _locals(scope->method()->max_locals(), NULL)
, _stack(scope->method()->max_stack())
, _locks()
D
duke 已提交
39
{
R
roland 已提交
40
  verify();
D
duke 已提交
41 42 43
}


R
roland 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56 57
ValueStack::ValueStack(ValueStack* copy_from, Kind kind, int bci)
  : _scope(copy_from->scope())
  , _caller_state(copy_from->caller_state())
  , _bci(bci)
  , _kind(kind)
  , _locals()
  , _stack()
  , _locks(copy_from->locks_size())
{
  assert(kind != EmptyExceptionState || !Compilation::current()->env()->jvmti_can_access_local_variables(), "need locals");
  if (kind != EmptyExceptionState) {
    // only allocate space if we need to copy the locals-array
    _locals = Values(copy_from->locals_size());
    _locals.appendAll(&copy_from->_locals);
D
duke 已提交
58
  }
R
roland 已提交
59 60 61 62 63 64 65 66

  if (kind != ExceptionState && kind != EmptyExceptionState) {
    if (kind == Parsing) {
      // stack will be modified, so reserve enough space to avoid resizing
      _stack = Values(scope()->method()->max_stack());
    } else {
      // stack will not be modified, so do not waste space
      _stack = Values(copy_from->stack_size());
D
duke 已提交
67
    }
R
roland 已提交
68
    _stack.appendAll(&copy_from->_stack);
D
duke 已提交
69
  }
R
roland 已提交
70 71 72 73

  _locks.appendAll(&copy_from->_locks);

  verify();
D
duke 已提交
74 75
}

R
roland 已提交
76

D
duke 已提交
77
bool ValueStack::is_same(ValueStack* s) {
R
roland 已提交
78 79
  if (scope() != s->scope()) return false;
  if (caller_state() != s->caller_state()) return false;
D
duke 已提交
80

R
roland 已提交
81 82 83
  if (locals_size() != s->locals_size()) return false;
  if (stack_size() != s->stack_size()) return false;
  if (locks_size() != s->locks_size()) return false;
D
duke 已提交
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

  // 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;
}

void ValueStack::clear_locals() {
  for (int i = _locals.length() - 1; i >= 0; i--) {
    _locals.at_put(i, NULL);
  }
}


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)
114
void ValueStack::apply(Values list, ValueVisitor* f) {
D
duke 已提交
115 116 117
  for (int i = 0; i < list.length(); i++) {
    Value* va = list.adr_at(i);
    Value v0 = *va;
R
roland 已提交
118 119
    if (v0 != NULL && !v0->type()->is_illegal()) {
      f->visit(va);
D
duke 已提交
120
#ifdef ASSERT
R
roland 已提交
121 122 123
      Value v1 = *va;
      assert(v1->type()->is_illegal() || v0->type()->tag() == v1->type()->tag(), "types must match");
      assert(!v1->type()->is_double_word() || list.at(i + 1) == NULL, "hi-word of doubleword value must be NULL");
D
duke 已提交
124
#endif
R
roland 已提交
125
      if (v0->type()->is_double_word()) i++;
D
duke 已提交
126 127 128 129 130
    }
  }
}


131
void ValueStack::values_do(ValueVisitor* f) {
D
duke 已提交
132 133 134
  ValueStack* state = this;
  for_each_state(state) {
    apply(state->_locals, f);
R
roland 已提交
135 136
    apply(state->_stack, f);
    apply(state->_locks, f);
D
duke 已提交
137 138 139 140 141 142 143 144 145 146 147 148 149 150
  }
}


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;
}


R
roland 已提交
151 152 153 154 155 156 157 158 159 160
int ValueStack::total_locks_size() const {
  int num_locks = 0;
  const ValueStack* state = this;
  for_each_state(state) {
    num_locks += state->locks_size();
  }
  return num_locks;
}

int ValueStack::lock(Value obj) {
D
duke 已提交
161
  _locks.push(obj);
R
roland 已提交
162 163 164
  int num_locks = total_locks_size();
  scope()->set_min_number_of_locks(num_locks);
  return num_locks - 1;
D
duke 已提交
165 166 167 168 169
}


int ValueStack::unlock() {
  _locks.pop();
R
roland 已提交
170
  return total_locks_size();
D
duke 已提交
171 172 173 174 175 176 177 178 179 180
}


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;

R
roland 已提交
181
  assert(!t->is_double_word() || _stack.at(index + 1) == NULL, "hi-word of doubleword value must be NULL");
D
duke 已提交
182 183 184 185 186 187 188 189 190 191 192
}

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
R
roland 已提交
193

D
duke 已提交
194
void ValueStack::print() {
R
roland 已提交
195
  scope()->method()->print_name();
D
duke 已提交
196 197 198 199 200 201 202
  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);
R
roland 已提交
203
      tty->print("%c%d ", t->type()->tchar(), t->id());
D
duke 已提交
204 205 206 207 208 209
      ip.print_instr(t);
      tty->cr();
    }
  }
  if (!no_active_locks()) {
    InstructionPrinter ip;
R
roland 已提交
210
    for (int i = 0; i < locks_size(); i++) {
D
duke 已提交
211 212 213 214 215
      Value t = lock_at(i);
      tty->print("lock %2d  ", i);
      if (t == NULL) {
        tty->print("this");
      } else {
R
roland 已提交
216
        tty->print("%c%d ", t->type()->tchar(), t->id());
D
duke 已提交
217 218 219 220 221 222 223 224 225 226 227 228 229 230
        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 {
R
roland 已提交
231
        tty->print("%c%d ", l->type()->tchar(), l->id());
D
duke 已提交
232 233 234 235 236 237
        ip.print_instr(l);
        if (l->type()->is_illegal() || l->type()->is_single_word()) i ++; else i += 2;
      }
      tty->cr();
    }
  }
R
roland 已提交
238 239 240 241

  if (caller_state() != NULL) {
    caller_state()->print();
  }
D
duke 已提交
242 243 244 245
}


void ValueStack::verify() {
R
roland 已提交
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
  assert(scope() != NULL, "scope must exist");
  if (caller_state() != NULL) {
    assert(caller_state()->scope() == scope()->caller(), "invalid caller scope");
    caller_state()->verify();
  }

  if (kind() == Parsing) {
    assert(bci() == -99, "bci not defined during parsing");
  } else {
    assert(bci() >= -1, "bci out of range");
    assert(bci() < scope()->method()->code_size(), "bci out of range");
    assert(bci() == SynchronizationEntryBCI || Bytecodes::is_defined(scope()->method()->java_code_at_bci(bci())), "make sure bci points at a real bytecode");
    assert(scope()->method()->liveness_at_bci(bci()).is_valid(), "liveness at bci must be valid");
  }

  int i;
  for (i = 0; i < stack_size(); i++) {
    Value v = _stack.at(i);
    if (v == NULL) {
      assert(_stack.at(i - 1)->type()->is_double_word(), "only hi-words are NULL on stack");
    } else if (v->type()->is_double_word()) {
      assert(_stack.at(i + 1) == NULL, "hi-word must be NULL");
    }
  }

  for (i = 0; i < locals_size(); i++) {
    Value v = _locals.at(i);
    if (v != NULL && v->type()->is_double_word()) {
      assert(_locals.at(i + 1) == NULL, "hi-word must be NULL");
    }
  }

  for_each_state_value(this, v,
    assert(v != NULL, "just test if state-iteration succeeds");
  );
D
duke 已提交
281 282
}
#endif // PRODUCT