diff src/share/vm/c1/c1_Instruction.hpp @ 1819:f02a8bbe6ed4

6986046: C1 valuestack cleanup Summary: fixes an historical oddity in C1 with inlining where all of the expression stacks are kept in the topmost ValueStack instead of being in their respective ValueStacks. Reviewed-by: never Contributed-by: Christian Wimmer <cwimmer@uci.edu>
author roland
date Tue, 29 Dec 2009 19:08:54 +0100
parents 3a294e483abc
children ad0638ff8ea4
line wrap: on
line diff
--- a/src/share/vm/c1/c1_Instruction.hpp	Wed Sep 22 23:51:03 2010 -0700
+++ b/src/share/vm/c1/c1_Instruction.hpp	Tue Dec 29 19:08:54 2009 +0100
@@ -38,7 +38,6 @@
 // serve factoring.
 
 class Instruction;
-class   HiWord;
 class   Phi;
 class   Local;
 class   Constant;
@@ -149,7 +148,6 @@
 
 class InstructionVisitor: public StackObj {
  public:
-          void do_HiWord         (HiWord*          x) { ShouldNotReachHere(); }
   virtual void do_Phi            (Phi*             x) = 0;
   virtual void do_Local          (Local*           x) = 0;
   virtual void do_Constant       (Constant*        x) = 0;
@@ -272,7 +270,9 @@
 class Instruction: public CompilationResourceObj {
  private:
   int          _id;                              // the unique instruction id
-  int          _bci;                             // the instruction bci
+#ifndef PRODUCT
+  int          _printable_bci;                   // the bci of the instruction for printing
+#endif
   int          _use_count;                       // the number of instructions refering to this value (w/o prev/next); only roots can have use count = 0 or > 1
   int          _pin_state;                       // set of PinReason describing the reason for pinning
   ValueType*   _type;                            // the instruction value type
@@ -281,17 +281,18 @@
   LIR_Opr      _operand;                         // LIR specific information
   unsigned int _flags;                           // Flag bits
 
+  ValueStack*  _state_before;                    // Copy of state with input operands still on stack (or NULL)
+  ValueStack*  _exception_state;                 // Copy of state for exception handling
   XHandlers*   _exception_handlers;              // Flat list of exception handlers covering this instruction
 
-#ifdef ASSERT
-  HiWord*      _hi_word;
-#endif
-
   friend class UseCountComputer;
   friend class BlockBegin;
 
+  void update_exception_state(ValueStack* state);
+
+  bool has_printable_bci() const                 { return NOT_PRODUCT(_printable_bci != -99) PRODUCT_ONLY(false); }
+
  protected:
-  void set_bci(int bci)                          { assert(bci == SynchronizationEntryBCI || bci >= 0, "illegal bci"); _bci = bci; }
   void set_type(ValueType* type) {
     assert(type != NULL, "type must exist");
     _type = type;
@@ -325,6 +326,7 @@
     NeedsPatchingFlag,
     ThrowIncompatibleClassChangeErrorFlag,
     ProfileMDOFlag,
+    IsLinkedInBlockFlag,
     InstructionLastFlag
   };
 
@@ -356,31 +358,31 @@
   }
 
   // creation
-  Instruction(ValueType* type, bool type_is_constant = false, bool create_hi = true)
-  : _bci(-99)
-  , _use_count(0)
+  Instruction(ValueType* type, ValueStack* state_before = NULL, bool type_is_constant = false, bool create_hi = true)
+  : _use_count(0)
+#ifndef PRODUCT
+  , _printable_bci(-99)
+#endif
   , _pin_state(0)
   , _type(type)
   , _next(NULL)
   , _subst(NULL)
   , _flags(0)
   , _operand(LIR_OprFact::illegalOpr)
+  , _state_before(state_before)
   , _exception_handlers(NULL)
-#ifdef ASSERT
-  , _hi_word(NULL)
-#endif
   {
+    check_state(state_before);
     assert(type != NULL && (!type->is_constant() || type_is_constant), "type must exist");
-#ifdef ASSERT
-    if (create_hi && type->is_double_word()) {
-      create_hi_word();
-    }
-#endif
+    update_exception_state(_state_before);
   }
 
   // accessors
   int id() const                                 { return _id; }
-  int bci() const                                { return _bci; }
+#ifndef PRODUCT
+  int printable_bci() const                      { assert(has_printable_bci(), "_printable_bci should have been set"); return _printable_bci; }
+  void set_printable_bci(int bci)                { NOT_PRODUCT(_printable_bci = bci;) }
+#endif
   int use_count() const                          { return _use_count; }
   int pin_state() const                          { return _pin_state; }
   bool is_pinned() const                         { return _pin_state != 0 || PinAllInstructions; }
@@ -393,9 +395,13 @@
 
   void set_needs_null_check(bool f)              { set_flag(NeedsNullCheckFlag, f); }
   bool needs_null_check() const                  { return check_flag(NeedsNullCheckFlag); }
+  bool is_linked() const                         { return check_flag(IsLinkedInBlockFlag); }
+  bool can_be_linked()                           { return as_Local() == NULL && as_Phi() == NULL; }
 
   bool has_uses() const                          { return use_count() > 0; }
-  bool is_root() const                           { return is_pinned() || use_count() > 1; }
+  ValueStack* state_before() const               { return _state_before; }
+  ValueStack* exception_state() const            { return _exception_state; }
+  virtual bool needs_exception_state() const     { return true; }
   XHandlers* exception_handlers() const          { return _exception_handlers; }
 
   // manipulation
@@ -403,17 +409,23 @@
   void pin()                                     { _pin_state |= PinUnknown; }
   // DANGEROUS: only used by EliminateStores
   void unpin(PinReason reason)                   { assert((reason & PinUnknown) == 0, "can't unpin unknown state"); _pin_state &= ~reason; }
-  virtual void set_lock_stack(ValueStack* l)     { /* do nothing*/ }
-  virtual ValueStack* lock_stack() const         { return NULL; }
+
+  Instruction* set_next(Instruction* next) {
+    assert(next->has_printable_bci(), "_printable_bci should have been set");
+    assert(next != NULL, "must not be NULL");
+    assert(as_BlockEnd() == NULL, "BlockEnd instructions must have no next");
+    assert(next->can_be_linked(), "shouldn't link these instructions into list");
+
+    next->set_flag(Instruction::IsLinkedInBlockFlag, true);
+    _next = next;
+    return next;
+  }
 
   Instruction* set_next(Instruction* next, int bci) {
-    if (next != NULL) {
-      assert(as_BlockEnd() == NULL, "BlockEnd instructions must have no next");
-      assert(next->as_Phi() == NULL && next->as_Local() == NULL, "shouldn't link these instructions into list");
-      next->set_bci(bci);
-    }
-    _next = next;
-    return next;
+#ifndef PRODUCT
+    next->set_printable_bci(bci);
+#endif
+    return set_next(next);
   }
 
   void set_subst(Instruction* subst)             {
@@ -423,14 +435,7 @@
     _subst = subst;
   }
   void set_exception_handlers(XHandlers *xhandlers) { _exception_handlers = xhandlers; }
-
-#ifdef ASSERT
-  // HiWord is used for debugging and is allocated early to avoid
-  // allocation at inconvenient points
-  HiWord* hi_word() { return _hi_word; }
-  void create_hi_word();
-#endif
-
+  void set_exception_state(ValueStack* s)        { check_state(s); _exception_state = s; }
 
   // machine-specifics
   void set_operand(LIR_Opr operand)              { assert(operand != LIR_OprFact::illegalOpr, "operand must exist"); _operand = operand; }
@@ -438,7 +443,6 @@
 
   // generic
   virtual Instruction*      as_Instruction()     { return this; } // to satisfy HASHING1 macro
-  virtual HiWord*           as_HiWord()          { return NULL; }
   virtual Phi*           as_Phi()          { return NULL; }
   virtual Local*            as_Local()           { return NULL; }
   virtual Constant*         as_Constant()        { return NULL; }
@@ -493,7 +497,7 @@
   virtual bool can_trap() const                  { return false; }
 
   virtual void input_values_do(ValueVisitor* f)   = 0;
-  virtual void state_values_do(ValueVisitor* f)   { /* usually no state - override on demand */ }
+  virtual void state_values_do(ValueVisitor* f);
   virtual void other_values_do(ValueVisitor* f)   { /* usually no other - override on demand */ }
           void       values_do(ValueVisitor* f)   { input_values_do(f); state_values_do(f); other_values_do(f); }
 
@@ -505,6 +509,7 @@
   HASHING1(Instruction, false, id())             // hashing disabled by default
 
   // debugging
+  static void check_state(ValueStack* state)     PRODUCT_RETURN;
   void print()                                   PRODUCT_RETURN;
   void print_line()                              PRODUCT_RETURN;
   void print(InstructionPrinter& ip)             PRODUCT_RETURN;
@@ -541,40 +546,6 @@
 #endif // ASSERT
 
 
-// A HiWord occupies the 'high word' of a 2-word
-// expression stack entry. Hi & lo words must be
-// paired on the expression stack (otherwise the
-// bytecode sequence is illegal). Note that 'hi'
-// refers to the IR expression stack format and
-// does *not* imply a machine word ordering. No
-// HiWords are used in optimized mode for speed,
-// but NULL pointers are used instead.
-
-LEAF(HiWord, Instruction)
- private:
-  Value _lo_word;
-
- public:
-  // creation
-  HiWord(Value lo_word)
-    : Instruction(illegalType, false, false),
-      _lo_word(lo_word) {
-    // hi-words are also allowed for illegal lo-words
-    assert(lo_word->type()->is_double_word() || lo_word->type()->is_illegal(),
-           "HiWord must be used for 2-word values only");
-  }
-
-  // accessors
-  Value lo_word() const                          { return _lo_word->subst(); }
-
-  // for invalidating of HiWords
-  void make_illegal()                            { set_type(illegalType); }
-
-  // generic
-  virtual void input_values_do(ValueVisitor* f)   { ShouldNotReachHere(); }
-};
-
-
 // A Phi is a phi function in the sense of SSA form. It stands for
 // the value of a local variable at the beginning of a join block.
 // A Phi consists of n operands, one for every incoming branch.
@@ -656,31 +627,25 @@
 
 
 LEAF(Constant, Instruction)
-  ValueStack* _state;
-
  public:
   // creation
   Constant(ValueType* type):
-      Instruction(type, true)
-  , _state(NULL) {
+      Instruction(type, NULL, true)
+  {
     assert(type->is_constant(), "must be a constant");
   }
 
-  Constant(ValueType* type, ValueStack* state):
-    Instruction(type, true)
-  , _state(state) {
-    assert(state != NULL, "only used for constants which need patching");
+  Constant(ValueType* type, ValueStack* state_before):
+    Instruction(type, state_before, true)
+  {
+    assert(state_before != NULL, "only used for constants which need patching");
     assert(type->is_constant(), "must be a constant");
     // since it's patching it needs to be pinned
     pin();
   }
 
-  ValueStack* state() const               { return _state; }
-
-  // generic
-  virtual bool can_trap() const                  { return state() != NULL; }
+  virtual bool can_trap() const                  { return state_before() != NULL; }
   virtual void input_values_do(ValueVisitor* f)   { /* no values */ }
-  virtual void other_values_do(ValueVisitor* f);
 
   virtual intx hash() const;
   virtual bool is_equal(Value v) const;
@@ -695,20 +660,16 @@
   Value       _obj;
   int         _offset;
   ciField*    _field;
-  ValueStack* _state_before;                     // state is set only for unloaded or uninitialized fields
-  ValueStack* _lock_stack;                       // contains lock and scope information
   NullCheck*  _explicit_null_check;              // For explicit null check elimination
 
  public:
   // creation
-  AccessField(Value obj, int offset, ciField* field, bool is_static, ValueStack* lock_stack,
+  AccessField(Value obj, int offset, ciField* field, bool is_static,
               ValueStack* state_before, bool is_loaded, bool is_initialized)
-  : Instruction(as_ValueType(field->type()->basic_type()))
+  : Instruction(as_ValueType(field->type()->basic_type()), state_before)
   , _obj(obj)
   , _offset(offset)
   , _field(field)
-  , _lock_stack(lock_stack)
-  , _state_before(state_before)
   , _explicit_null_check(NULL)
   {
     set_needs_null_check(!is_static);
@@ -734,13 +695,11 @@
   bool is_static() const                         { return check_flag(IsStaticFlag); }
   bool is_loaded() const                         { return check_flag(IsLoadedFlag); }
   bool is_initialized() const                    { return check_flag(IsInitializedFlag); }
-  ValueStack* state_before() const               { return _state_before; }
-  ValueStack* lock_stack() const                 { return _lock_stack; }
   NullCheck* explicit_null_check() const         { return _explicit_null_check; }
   bool needs_patching() const                    { return check_flag(NeedsPatchingFlag); }
 
   // manipulation
-  void set_lock_stack(ValueStack* l)             { _lock_stack = l; }
+
   // Under certain circumstances, if a previous NullCheck instruction
   // proved the target object non-null, we can eliminate the explicit
   // null check and do an implicit one, simply specifying the debug
@@ -751,16 +710,15 @@
   // generic
   virtual bool can_trap() const                  { return needs_null_check() || needs_patching(); }
   virtual void input_values_do(ValueVisitor* f)   { f->visit(&_obj); }
-  virtual void other_values_do(ValueVisitor* f);
 };
 
 
 LEAF(LoadField, AccessField)
  public:
   // creation
-  LoadField(Value obj, int offset, ciField* field, bool is_static, ValueStack* lock_stack,
+  LoadField(Value obj, int offset, ciField* field, bool is_static,
             ValueStack* state_before, bool is_loaded, bool is_initialized)
-  : AccessField(obj, offset, field, is_static, lock_stack, state_before, is_loaded, is_initialized)
+  : AccessField(obj, offset, field, is_static, state_before, is_loaded, is_initialized)
   {}
 
   ciType* declared_type() const;
@@ -777,9 +735,9 @@
 
  public:
   // creation
-  StoreField(Value obj, int offset, ciField* field, Value value, bool is_static, ValueStack* lock_stack,
+  StoreField(Value obj, int offset, ciField* field, Value value, bool is_static,
              ValueStack* state_before, bool is_loaded, bool is_initialized)
-  : AccessField(obj, offset, field, is_static, lock_stack, state_before, is_loaded, is_initialized)
+  : AccessField(obj, offset, field, is_static, state_before, is_loaded, is_initialized)
   , _value(value)
   {
     set_flag(NeedsWriteBarrierFlag, as_ValueType(field_type())->is_object());
@@ -799,29 +757,23 @@
 BASE(AccessArray, Instruction)
  private:
   Value       _array;
-  ValueStack* _lock_stack;
 
  public:
   // creation
-  AccessArray(ValueType* type, Value array, ValueStack* lock_stack)
-  : Instruction(type)
+  AccessArray(ValueType* type, Value array, ValueStack* state_before)
+  : Instruction(type, state_before)
   , _array(array)
-  , _lock_stack(lock_stack) {
+  {
     set_needs_null_check(true);
     ASSERT_VALUES
     pin(); // instruction with side effect (null exception or range check throwing)
   }
 
   Value array() const                            { return _array; }
-  ValueStack* lock_stack() const                 { return _lock_stack; }
-
-  // setters
-  void set_lock_stack(ValueStack* l)             { _lock_stack = l; }
 
   // generic
   virtual bool can_trap() const                  { return needs_null_check(); }
   virtual void input_values_do(ValueVisitor* f)   { f->visit(&_array); }
-  virtual void other_values_do(ValueVisitor* f);
 };
 
 
@@ -831,8 +783,8 @@
 
  public:
   // creation
-  ArrayLength(Value array, ValueStack* lock_stack)
-  : AccessArray(intType, array, lock_stack)
+  ArrayLength(Value array, ValueStack* state_before)
+  : AccessArray(intType, array, state_before)
   , _explicit_null_check(NULL) {}
 
   // accessors
@@ -855,8 +807,8 @@
 
  public:
   // creation
-  AccessIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* lock_stack)
-  : AccessArray(as_ValueType(elt_type), array, lock_stack)
+  AccessIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before)
+  : AccessArray(as_ValueType(elt_type), array, state_before)
   , _index(index)
   , _length(length)
   , _elt_type(elt_type)
@@ -883,8 +835,8 @@
 
  public:
   // creation
-  LoadIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* lock_stack)
-  : AccessIndexed(array, index, length, elt_type, lock_stack)
+  LoadIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before)
+  : AccessIndexed(array, index, length, elt_type, state_before)
   , _explicit_null_check(NULL) {}
 
   // accessors
@@ -910,8 +862,8 @@
   int       _profiled_bci;
  public:
   // creation
-  StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* lock_stack)
-  : AccessIndexed(array, index, length, elt_type, lock_stack)
+  StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before)
+  : AccessIndexed(array, index, length, elt_type, state_before)
   , _value(value), _profiled_method(NULL), _profiled_bci(0)
   {
     set_flag(NeedsWriteBarrierFlag, (as_ValueType(elt_type)->is_object()));
@@ -922,7 +874,6 @@
 
   // accessors
   Value value() const                            { return _value; }
-  IRScope* scope() const;                        // the state's scope
   bool needs_write_barrier() const               { return check_flag(NeedsWriteBarrierFlag); }
   bool needs_store_check() const                 { return check_flag(NeedsStoreCheckFlag); }
   // Helpers for methodDataOop profiling
@@ -963,7 +914,12 @@
 
  public:
   // creation
-  Op2(ValueType* type, Bytecodes::Code op, Value x, Value y) : Instruction(type), _op(op), _x(x), _y(y) {
+  Op2(ValueType* type, Bytecodes::Code op, Value x, Value y, ValueStack* state_before = NULL)
+  : Instruction(type, state_before)
+  , _op(op)
+  , _x(x)
+  , _y(y)
+  {
     ASSERT_VALUES
   }
 
@@ -985,28 +941,21 @@
 
 
 LEAF(ArithmeticOp, Op2)
- private:
-  ValueStack* _lock_stack;                       // used only for division operations
  public:
   // creation
-  ArithmeticOp(Bytecodes::Code op, Value x, Value y, bool is_strictfp, ValueStack* lock_stack)
-  : Op2(x->type()->meet(y->type()), op, x, y)
-  ,  _lock_stack(lock_stack) {
+  ArithmeticOp(Bytecodes::Code op, Value x, Value y, bool is_strictfp, ValueStack* state_before)
+  : Op2(x->type()->meet(y->type()), op, x, y, state_before)
+  {
     set_flag(IsStrictfpFlag, is_strictfp);
     if (can_trap()) pin();
   }
 
   // accessors
-  ValueStack* lock_stack() const                 { return _lock_stack; }
   bool        is_strictfp() const                { return check_flag(IsStrictfpFlag); }
 
-  // setters
-  void set_lock_stack(ValueStack* l)             { _lock_stack = l; }
-
   // generic
   virtual bool is_commutative() const;
   virtual bool can_trap() const;
-  virtual void other_values_do(ValueVisitor* f);
   HASHING3(Op2, true, op(), x()->subst(), y()->subst())
 };
 
@@ -1033,21 +982,14 @@
 
 
 LEAF(CompareOp, Op2)
- private:
-  ValueStack* _state_before;                     // for deoptimization, when canonicalizing
  public:
   // creation
   CompareOp(Bytecodes::Code op, Value x, Value y, ValueStack* state_before)
-  : Op2(intType, op, x, y)
-  , _state_before(state_before)
+  : Op2(intType, op, x, y, state_before)
   {}
 
-  // accessors
-  ValueStack* state_before() const               { return _state_before; }
-
   // generic
   HASHING3(Op2, true, op(), x()->subst(), y()->subst())
-  virtual void other_values_do(ValueVisitor* f);
 };
 
 
@@ -1103,11 +1045,13 @@
 LEAF(NullCheck, Instruction)
  private:
   Value       _obj;
-  ValueStack* _lock_stack;
 
  public:
   // creation
-  NullCheck(Value obj, ValueStack* lock_stack) : Instruction(obj->type()->base()), _obj(obj), _lock_stack(lock_stack) {
+  NullCheck(Value obj, ValueStack* state_before)
+  : Instruction(obj->type()->base(), state_before)
+  , _obj(obj)
+  {
     ASSERT_VALUES
     set_can_trap(true);
     assert(_obj->type()->is_object(), "null check must be applied to objects only");
@@ -1116,16 +1060,13 @@
 
   // accessors
   Value obj() const                              { return _obj; }
-  ValueStack* lock_stack() const                 { return _lock_stack; }
 
   // setters
-  void set_lock_stack(ValueStack* l)             { _lock_stack = l; }
   void set_can_trap(bool can_trap)               { set_flag(CanTrapFlag, can_trap); }
 
   // generic
   virtual bool can_trap() const                  { return check_flag(CanTrapFlag); /* null-check elimination sets to false */ }
   virtual void input_values_do(ValueVisitor* f)   { f->visit(&_obj); }
-  virtual void other_values_do(ValueVisitor* f);
   HASHING1(NullCheck, true, obj()->subst())
 };
 
@@ -1139,7 +1080,10 @@
 
  public:
   // creation
-  StateSplit(ValueType* type) : Instruction(type), _state(NULL) {
+  StateSplit(ValueType* type, ValueStack* state_before = NULL)
+  : Instruction(type, state_before)
+  , _state(NULL)
+  {
     pin(PinStateSplitConstructor);
   }
 
@@ -1148,7 +1092,7 @@
   IRScope* scope() const;                        // the state's scope
 
   // manipulation
-  void set_state(ValueStack* state)              { _state = state; }
+  void set_state(ValueStack* state)              { assert(_state == NULL, "overwriting existing state"); check_state(state); _state = state; }
 
   // generic
   virtual void input_values_do(ValueVisitor* f)   { /* no values */ }
@@ -1164,7 +1108,6 @@
   BasicTypeList*  _signature;
   int             _vtable_index;
   ciMethod*       _target;
-  ValueStack*     _state_before;  // Required for deoptimization.
 
  public:
   // creation
@@ -1180,7 +1123,6 @@
   int vtable_index() const                       { return _vtable_index; }
   BasicTypeList* signature() const               { return _signature; }
   ciMethod* target() const                       { return _target; }
-  ValueStack* state_before() const               { return _state_before; }
 
   // Returns false if target is not loaded
   bool target_is_final() const                   { return check_flag(TargetIsFinalFlag); }
@@ -1191,6 +1133,8 @@
   // JSR 292 support
   bool is_invokedynamic() const                  { return code() == Bytecodes::_invokedynamic; }
 
+  virtual bool needs_exception_state() const     { return false; }
+
   // generic
   virtual bool can_trap() const                  { return true; }
   virtual void input_values_do(ValueVisitor* f) {
@@ -1208,11 +1152,16 @@
 
  public:
   // creation
-  NewInstance(ciInstanceKlass* klass) : StateSplit(instanceType), _klass(klass) {}
+  NewInstance(ciInstanceKlass* klass, ValueStack* state_before)
+  : StateSplit(instanceType, state_before)
+  , _klass(klass)
+  {}
 
   // accessors
   ciInstanceKlass* klass() const                 { return _klass; }
 
+  virtual bool needs_exception_state() const     { return false; }
+
   // generic
   virtual bool can_trap() const                  { return true; }
   ciType* exact_type() const;
@@ -1222,22 +1171,24 @@
 BASE(NewArray, StateSplit)
  private:
   Value       _length;
-  ValueStack* _state_before;
 
  public:
   // creation
-  NewArray(Value length, ValueStack* state_before) : StateSplit(objectType), _length(length), _state_before(state_before) {
+  NewArray(Value length, ValueStack* state_before)
+  : StateSplit(objectType, state_before)
+  , _length(length)
+  {
     // Do not ASSERT_VALUES since length is NULL for NewMultiArray
   }
 
   // accessors
-  ValueStack* state_before() const               { return _state_before; }
   Value length() const                           { return _length; }
 
+  virtual bool needs_exception_state() const     { return false; }
+
   // generic
   virtual bool can_trap() const                  { return true; }
   virtual void input_values_do(ValueVisitor* f)   { StateSplit::input_values_do(f); f->visit(&_length); }
-  virtual void other_values_do(ValueVisitor* f);
 };
 
 
@@ -1247,7 +1198,10 @@
 
  public:
   // creation
-  NewTypeArray(Value length, BasicType elt_type) : NewArray(length, NULL), _elt_type(elt_type) {}
+  NewTypeArray(Value length, BasicType elt_type, ValueStack* state_before)
+  : NewArray(length, state_before)
+  , _elt_type(elt_type)
+  {}
 
   // accessors
   BasicType elt_type() const                     { return _elt_type; }
@@ -1303,7 +1257,6 @@
  private:
   ciKlass*    _klass;
   Value       _obj;
-  ValueStack* _state_before;
 
   ciMethod* _profiled_method;
   int       _profiled_bci;
@@ -1311,14 +1264,13 @@
  public:
   // creation
   TypeCheck(ciKlass* klass, Value obj, ValueType* type, ValueStack* state_before)
-  : StateSplit(type), _klass(klass), _obj(obj), _state_before(state_before),
+  : StateSplit(type, state_before), _klass(klass), _obj(obj),
     _profiled_method(NULL), _profiled_bci(0) {
     ASSERT_VALUES
     set_direct_compare(false);
   }
 
   // accessors
-  ValueStack* state_before() const               { return _state_before; }
   ciKlass* klass() const                         { return _klass; }
   Value obj() const                              { return _obj; }
   bool is_loaded() const                         { return klass() != NULL; }
@@ -1330,7 +1282,6 @@
   // generic
   virtual bool can_trap() const                  { return true; }
   virtual void input_values_do(ValueVisitor* f)   { StateSplit::input_values_do(f); f->visit(&_obj); }
-  virtual void other_values_do(ValueVisitor* f);
 
   // Helpers for methodDataOop profiling
   void set_should_profile(bool value)                { set_flag(ProfileMDOFlag, value); }
@@ -1364,6 +1315,8 @@
  public:
   // creation
   InstanceOf(ciKlass* klass, Value obj, ValueStack* state_before) : TypeCheck(klass, obj, intType, state_before) {}
+
+  virtual bool needs_exception_state() const     { return false; }
 };
 
 
@@ -1374,8 +1327,8 @@
 
  public:
   // creation
-  AccessMonitor(Value obj, int monitor_no)
-  : StateSplit(illegalType)
+  AccessMonitor(Value obj, int monitor_no, ValueStack* state_before = NULL)
+  : StateSplit(illegalType, state_before)
   , _obj(obj)
   , _monitor_no(monitor_no)
   {
@@ -1393,22 +1346,14 @@
 
 
 LEAF(MonitorEnter, AccessMonitor)
- private:
-  ValueStack* _lock_stack_before;
-
  public:
   // creation
-  MonitorEnter(Value obj, int monitor_no, ValueStack* lock_stack_before)
-  : AccessMonitor(obj, monitor_no)
-  , _lock_stack_before(lock_stack_before)
+  MonitorEnter(Value obj, int monitor_no, ValueStack* state_before)
+  : AccessMonitor(obj, monitor_no, state_before)
   {
     ASSERT_VALUES
   }
 
-  // accessors
-  ValueStack* lock_stack_before() const          { return _lock_stack_before; }
-  virtual void state_values_do(ValueVisitor* f);
-
   // generic
   virtual bool can_trap() const                  { return true; }
 };
@@ -1417,7 +1362,11 @@
 LEAF(MonitorExit, AccessMonitor)
  public:
   // creation
-  MonitorExit(Value obj, int monitor_no) : AccessMonitor(obj, monitor_no) {}
+  MonitorExit(Value obj, int monitor_no)
+  : AccessMonitor(obj, monitor_no, NULL)
+  {
+    ASSERT_VALUES
+  }
 };
 
 
@@ -1425,7 +1374,6 @@
  private:
   vmIntrinsics::ID _id;
   Values*          _args;
-  ValueStack*      _lock_stack;
   Value            _recv;
 
  public:
@@ -1440,13 +1388,12 @@
             vmIntrinsics::ID id,
             Values* args,
             bool has_receiver,
-            ValueStack* lock_stack,
+            ValueStack* state_before,
             bool preserves_state,
             bool cantrap = true)
-  : StateSplit(type)
+  : StateSplit(type, state_before)
   , _id(id)
   , _args(args)
-  , _lock_stack(lock_stack)
   , _recv(NULL)
   {
     assert(args != NULL, "args must exist");
@@ -1468,7 +1415,6 @@
   vmIntrinsics::ID id() const                    { return _id; }
   int number_of_arguments() const                { return _args->length(); }
   Value argument_at(int i) const                 { return _args->at(i); }
-  ValueStack* lock_stack() const                 { return _lock_stack; }
 
   bool has_receiver() const                      { return (_recv != NULL); }
   Value receiver() const                         { assert(has_receiver(), "must have receiver"); return _recv; }
@@ -1480,8 +1426,6 @@
     StateSplit::input_values_do(f);
     for (int i = 0; i < _args->length(); i++) f->visit(_args->adr_at(i));
   }
-  virtual void state_values_do(ValueVisitor* f);
-
 };
 
 
@@ -1490,6 +1434,7 @@
 LEAF(BlockBegin, StateSplit)
  private:
   int        _block_id;                          // the unique block id
+  int        _bci;                               // start-bci of block
   int        _depth_first_number;                // number of this block in a depth-first ordering
   int        _linear_scan_number;                // number of this block in linear-scan ordering
   int        _loop_depth;                        // the loop nesting level of this block
@@ -1546,6 +1491,7 @@
   // creation
   BlockBegin(int bci)
   : StateSplit(illegalType)
+  , _bci(bci)
   , _depth_first_number(-1)
   , _linear_scan_number(-1)
   , _loop_depth(0)
@@ -1570,11 +1516,14 @@
   , _total_preds(0)
   , _stores_to_locals()
   {
-    set_bci(bci);
+#ifndef PRODUCT
+    set_printable_bci(bci);
+#endif
   }
 
   // accessors
   int block_id() const                           { return _block_id; }
+  int bci() const                                { return _bci; }
   BlockList* successors()                        { return &_successors; }
   BlockBegin* dominator() const                  { return _dominator; }
   int loop_depth() const                         { return _loop_depth; }
@@ -1596,7 +1545,6 @@
   BitMap& stores_to_locals()                     { return _stores_to_locals; }
 
   // manipulation
-  void set_bci(int bci)                          { Instruction::set_bci(bci); }
   void set_dominator(BlockBegin* dom)            { _dominator = dom; }
   void set_loop_depth(int d)                     { _loop_depth = d; }
   void set_depth_first_number(int dfn)           { _depth_first_number = dfn; }
@@ -1694,7 +1642,6 @@
  private:
   BlockBegin* _begin;
   BlockList*  _sux;
-  ValueStack* _state_before;
 
  protected:
   BlockList* sux() const                         { return _sux; }
@@ -1710,24 +1657,20 @@
  public:
   // creation
   BlockEnd(ValueType* type, ValueStack* state_before, bool is_safepoint)
-  : StateSplit(type)
+  : StateSplit(type, state_before)
   , _begin(NULL)
   , _sux(NULL)
-  , _state_before(state_before) {
+  {
     set_flag(IsSafepointFlag, is_safepoint);
   }
 
   // accessors
-  ValueStack* state_before() const               { return _state_before; }
   bool is_safepoint() const                      { return check_flag(IsSafepointFlag); }
   BlockBegin* begin() const                      { return _begin; }
 
   // manipulation
   void set_begin(BlockBegin* begin);
 
-  // generic
-  virtual void other_values_do(ValueVisitor* f);
-
   // successors
   int number_of_sux() const                      { return _sux != NULL ? _sux->length() : 0; }
   BlockBegin* sux_at(int i) const                { return _sux->at(i); }
@@ -1919,6 +1862,8 @@
   Value tag() const                              { return _tag; }
   int length() const                             { return number_of_sux() - 1; }
 
+  virtual bool needs_exception_state() const     { return false; }
+
   // generic
   virtual void input_values_do(ValueVisitor* f)   { BlockEnd::input_values_do(f); f->visit(&_tag); }
 };
@@ -1996,7 +1941,6 @@
   // generic
   virtual bool can_trap() const                  { return true; }
   virtual void input_values_do(ValueVisitor* f)   { BlockEnd::input_values_do(f); f->visit(&_exception); }
-  virtual void state_values_do(ValueVisitor* f);
 };
 
 
@@ -2091,7 +2035,6 @@
 
   // generic
   virtual void input_values_do(ValueVisitor* f)   { }
-  virtual void other_values_do(ValueVisitor* f)   { }
 };