src/share/vm/ci/ciField.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8161987 Sdiff src/share/vm/ci

src/share/vm/ci/ciField.hpp

Print this page
rev 8156 : 8157181: Compilers accept modification of final fields outside initializer methods
Summary: Track initialized final field updates; disable constant folding if an update is detected.
Reviewed-by: vlivanov, dnsimon, forax, never, kvn, coleenp


 107   // How big is this field in memory?
 108   int size_in_bytes() { return type2aelembytes(layout_type()); }
 109 
 110   // What is the offset of this field?
 111   int offset() {
 112     assert(_offset >= 1, "illegal call to offset()");
 113     return _offset;
 114   }
 115 
 116   // Same question, explicit units.  (Fields are aligned to the byte level.)
 117   int offset_in_bytes() {
 118     return offset();
 119   }
 120 
 121   // Is this field shared?
 122   bool is_shared() {
 123     // non-static fields of shared holders are cached
 124     return _holder->is_shared() && !is_static();
 125   }
 126 
 127   // Is this field a constant?
 128   //
 129   // Clarification: A field is considered constant if:
 130   //   1. The field is both static and final
 131   //   2. The canonical holder of the field has undergone
 132   //      static initialization.
 133   //   3. If the field is an object or array, then the oop
 134   //      in question is allocated in perm space.
 135   //   4. The field is not one of the special static/final
 136   //      non-constant fields.  These are java.lang.System.in
 137   //      and java.lang.System.out.  Abomination.
 138   //
 139   // A field is also considered constant if it is marked @Stable
 140   // and is non-null (or non-zero, if a primitive).
 141   // For non-static fields, the null/zero check must be
 142   // arranged by the user, as constant_value().is_null_or_zero().
 143   bool is_constant() { return _is_constant; }
 144 
 145   // Get the constant value of this field.
 146   ciConstant constant_value() {
 147     assert(is_static() && is_constant(), "illegal call to constant_value()");
 148     return _constant_value;
 149   }
 150 
 151   // Get the constant value of non-static final field in the given
 152   // object.
 153   ciConstant constant_value_of(ciObject* object) {
 154     assert(!is_static() && is_constant(), "only if field is non-static constant");
 155     assert(object->is_instance(), "must be instance");
 156     return object->as_instance()->field_value(this);
 157   }
 158 
 159   // Check for link time errors.  Accessing a field from a
 160   // certain class via a certain bytecode may or may not be legal.
 161   // This call checks to see if an exception may be raised by
 162   // an access of this field.
 163   //
 164   // Usage note: if the same field is accessed multiple times
 165   // in the same compilation, will_link will need to be checked
 166   // at each point of access.
 167   bool will_link(ciInstanceKlass* accessing_klass,
 168                  Bytecodes::Code bc);
 169 
 170   // Java access flags
 171   bool is_public      () { return flags().is_public(); }
 172   bool is_private     () { return flags().is_private(); }
 173   bool is_protected   () { return flags().is_protected(); }
 174   bool is_static      () { return flags().is_static(); }
 175   bool is_final       () { return flags().is_final(); }
 176   bool is_stable      () { return flags().is_stable(); }
 177   bool is_volatile    () { return flags().is_volatile(); }
 178   bool is_transient   () { return flags().is_transient(); }



 179 
 180   bool is_call_site_target() {
 181     ciInstanceKlass* callsite_klass = CURRENT_ENV->CallSite_klass();
 182     if (callsite_klass == NULL)
 183       return false;
 184     return (holder()->is_subclass_of(callsite_klass) && (name() == ciSymbol::target_name()));
 185   }
 186 
 187   // Debugging output
 188   void print();
 189   void print_name_on(outputStream* st);
 190 };
 191 
 192 #endif // SHARE_VM_CI_CIFIELD_HPP


 107   // How big is this field in memory?
 108   int size_in_bytes() { return type2aelembytes(layout_type()); }
 109 
 110   // What is the offset of this field?
 111   int offset() {
 112     assert(_offset >= 1, "illegal call to offset()");
 113     return _offset;
 114   }
 115 
 116   // Same question, explicit units.  (Fields are aligned to the byte level.)
 117   int offset_in_bytes() {
 118     return offset();
 119   }
 120 
 121   // Is this field shared?
 122   bool is_shared() {
 123     // non-static fields of shared holders are cached
 124     return _holder->is_shared() && !is_static();
 125   }
 126 
 127   // Is this field a constant? See ciField::initialize_from() for details
 128   // about how a field is determined to be constant.














 129   bool is_constant() { return _is_constant; }
 130 
 131   // Get the constant value of this field.
 132   ciConstant constant_value() {
 133     assert(is_static() && is_constant(), "illegal call to constant_value()");
 134     return _constant_value;
 135   }
 136 
 137   // Get the constant value of non-static final field in the given
 138   // object.
 139   ciConstant constant_value_of(ciObject* object) {
 140     assert(!is_static() && is_constant(), "only if field is non-static constant");
 141     assert(object->is_instance(), "must be instance");
 142     return object->as_instance()->field_value(this);
 143   }
 144 
 145   // Check for link time errors.  Accessing a field from a
 146   // certain class via a certain bytecode may or may not be legal.
 147   // This call checks to see if an exception may be raised by
 148   // an access of this field.
 149   //
 150   // Usage note: if the same field is accessed multiple times
 151   // in the same compilation, will_link will need to be checked
 152   // at each point of access.
 153   bool will_link(ciInstanceKlass* accessing_klass,
 154                  Bytecodes::Code bc);
 155 
 156   // Java access flags
 157   bool is_public      () { return flags().is_public(); }
 158   bool is_private     () { return flags().is_private(); }
 159   bool is_protected   () { return flags().is_protected(); }
 160   bool is_static      () { return flags().is_static(); }
 161   bool is_final       () { return flags().is_final(); }
 162   bool is_stable      () { return flags().is_stable(); }
 163   bool is_volatile    () { return flags().is_volatile(); }
 164   bool is_transient   () { return flags().is_transient(); }
 165   // The field is modified outside of instance initializer methods
 166   // (or class/initializer methods if the field is static).
 167   bool has_initialized_final_update() { return flags().has_initialized_final_update(); }
 168 
 169   bool is_call_site_target() {
 170     ciInstanceKlass* callsite_klass = CURRENT_ENV->CallSite_klass();
 171     if (callsite_klass == NULL)
 172       return false;
 173     return (holder()->is_subclass_of(callsite_klass) && (name() == ciSymbol::target_name()));
 174   }
 175 
 176   // Debugging output
 177   void print();
 178   void print_name_on(outputStream* st);
 179 };
 180 
 181 #endif // SHARE_VM_CI_CIFIELD_HPP
src/share/vm/ci/ciField.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File