< prev index next >

src/hotspot/share/oops/cpCache.cpp

Print this page
rev 47400 : [mq]: cmpxchg_ptr
rev 47406 : [mq]: assembler_cmpxchg


  74                                        int field_index_or_method_params) {
  75   assert(state < number_of_states, "Invalid state in make_flags");
  76   int f = ((int)state << tos_state_shift) | option_bits | field_index_or_method_params;
  77   // Preserve existing flag bit values
  78   // The low bits are a field offset, or else the method parameter size.
  79 #ifdef ASSERT
  80   TosState old_state = flag_state();
  81   assert(old_state == (TosState)0 || old_state == state,
  82          "inconsistent cpCache flags state");
  83 #endif
  84   return (_flags | f) ;
  85 }
  86 
  87 void ConstantPoolCacheEntry::set_bytecode_1(Bytecodes::Code code) {
  88 #ifdef ASSERT
  89   // Read once.
  90   volatile Bytecodes::Code c = bytecode_1();
  91   assert(c == 0 || c == code || code == 0, "update must be consistent");
  92 #endif
  93   // Need to flush pending stores here before bytecode is written.
  94   OrderAccess::release_store_ptr(&_indices, _indices | ((u_char)code << bytecode_1_shift));
  95 }
  96 
  97 void ConstantPoolCacheEntry::set_bytecode_2(Bytecodes::Code code) {
  98 #ifdef ASSERT
  99   // Read once.
 100   volatile Bytecodes::Code c = bytecode_2();
 101   assert(c == 0 || c == code || code == 0, "update must be consistent");
 102 #endif
 103   // Need to flush pending stores here before bytecode is written.
 104   OrderAccess::release_store_ptr(&_indices, _indices | ((u_char)code << bytecode_2_shift));
 105 }
 106 
 107 // Sets f1, ordering with previous writes.
 108 void ConstantPoolCacheEntry::release_set_f1(Metadata* f1) {
 109   assert(f1 != NULL, "");
 110   OrderAccess::release_store_ptr((HeapWord*) &_f1, f1);
 111 }
 112 
 113 // Sets flags, but only if the value was previously zero.
 114 bool ConstantPoolCacheEntry::init_flags_atomic(intptr_t flags) {
 115   intptr_t result = Atomic::cmpxchg_ptr(flags, &_flags, 0);
 116   return (result == 0);
 117 }
 118 
 119 // Note that concurrent update of both bytecodes can leave one of them
 120 // reset to zero.  This is harmless; the interpreter will simply re-resolve
 121 // the damaged entry.  More seriously, the memory synchronization is needed
 122 // to flush other fields (f1, f2) completely to memory before the bytecodes
 123 // are updated, lest other processors see a non-zero bytecode but zero f1/f2.
 124 void ConstantPoolCacheEntry::set_field(Bytecodes::Code get_code,
 125                                        Bytecodes::Code put_code,
 126                                        Klass* field_holder,
 127                                        int field_index,
 128                                        int field_offset,
 129                                        TosState field_type,
 130                                        bool is_final,
 131                                        bool is_volatile,
 132                                        Klass* root_klass) {
 133   set_f1(field_holder);
 134   set_f2(field_offset);
 135   assert((field_index & field_index_mask) == field_index,


 137   set_field_flags(field_type,
 138                   ((is_volatile ? 1 : 0) << is_volatile_shift) |
 139                   ((is_final    ? 1 : 0) << is_final_shift),
 140                   field_index);
 141   set_bytecode_1(get_code);
 142   set_bytecode_2(put_code);
 143   NOT_PRODUCT(verify(tty));
 144 }
 145 
 146 void ConstantPoolCacheEntry::set_parameter_size(int value) {
 147   // This routine is called only in corner cases where the CPCE is not yet initialized.
 148   // See AbstractInterpreter::deopt_continue_after_entry.
 149   assert(_flags == 0 || parameter_size() == 0 || parameter_size() == value,
 150          "size must not change: parameter_size=%d, value=%d", parameter_size(), value);
 151   // Setting the parameter size by itself is only safe if the
 152   // current value of _flags is 0, otherwise another thread may have
 153   // updated it and we don't want to overwrite that value.  Don't
 154   // bother trying to update it once it's nonzero but always make
 155   // sure that the final parameter size agrees with what was passed.
 156   if (_flags == 0) {
 157     Atomic::cmpxchg_ptr((value & parameter_size_mask), &_flags, 0);

 158   }
 159   guarantee(parameter_size() == value,
 160             "size must not change: parameter_size=%d, value=%d", parameter_size(), value);
 161 }
 162 
 163 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
 164                                                        const methodHandle& method,
 165                                                        int vtable_index,
 166                                                        bool sender_is_interface) {
 167   bool is_vtable_call = (vtable_index >= 0);  // FIXME: split this method on this boolean
 168   assert(method->interpreter_entry() != NULL, "should have been set at this point");
 169   assert(!method->is_obsolete(),  "attempt to write obsolete method to cpCache");
 170 
 171   int byte_no = -1;
 172   bool change_to_virtual = false;
 173 
 174   switch (invoke_code) {
 175     case Bytecodes::_invokeinterface:
 176       // We get here from InterpreterRuntime::resolve_invoke when an invokeinterface
 177       // instruction somehow links to a non-interface method (in Object).




  74                                        int field_index_or_method_params) {
  75   assert(state < number_of_states, "Invalid state in make_flags");
  76   int f = ((int)state << tos_state_shift) | option_bits | field_index_or_method_params;
  77   // Preserve existing flag bit values
  78   // The low bits are a field offset, or else the method parameter size.
  79 #ifdef ASSERT
  80   TosState old_state = flag_state();
  81   assert(old_state == (TosState)0 || old_state == state,
  82          "inconsistent cpCache flags state");
  83 #endif
  84   return (_flags | f) ;
  85 }
  86 
  87 void ConstantPoolCacheEntry::set_bytecode_1(Bytecodes::Code code) {
  88 #ifdef ASSERT
  89   // Read once.
  90   volatile Bytecodes::Code c = bytecode_1();
  91   assert(c == 0 || c == code || code == 0, "update must be consistent");
  92 #endif
  93   // Need to flush pending stores here before bytecode is written.
  94   OrderAccess::release_store(&_indices, _indices | ((u_char)code << bytecode_1_shift));
  95 }
  96 
  97 void ConstantPoolCacheEntry::set_bytecode_2(Bytecodes::Code code) {
  98 #ifdef ASSERT
  99   // Read once.
 100   volatile Bytecodes::Code c = bytecode_2();
 101   assert(c == 0 || c == code || code == 0, "update must be consistent");
 102 #endif
 103   // Need to flush pending stores here before bytecode is written.
 104   OrderAccess::release_store(&_indices, _indices | ((u_char)code << bytecode_2_shift));
 105 }
 106 
 107 // Sets f1, ordering with previous writes.
 108 void ConstantPoolCacheEntry::release_set_f1(Metadata* f1) {
 109   assert(f1 != NULL, "");
 110   OrderAccess::release_store(&_f1, f1);
 111 }
 112 
 113 // Sets flags, but only if the value was previously zero.
 114 bool ConstantPoolCacheEntry::init_flags_atomic(intptr_t flags) {
 115   intptr_t result = Atomic::cmpxchg(flags, &_flags, (intptr_t)0);
 116   return (result == 0);
 117 }
 118 
 119 // Note that concurrent update of both bytecodes can leave one of them
 120 // reset to zero.  This is harmless; the interpreter will simply re-resolve
 121 // the damaged entry.  More seriously, the memory synchronization is needed
 122 // to flush other fields (f1, f2) completely to memory before the bytecodes
 123 // are updated, lest other processors see a non-zero bytecode but zero f1/f2.
 124 void ConstantPoolCacheEntry::set_field(Bytecodes::Code get_code,
 125                                        Bytecodes::Code put_code,
 126                                        Klass* field_holder,
 127                                        int field_index,
 128                                        int field_offset,
 129                                        TosState field_type,
 130                                        bool is_final,
 131                                        bool is_volatile,
 132                                        Klass* root_klass) {
 133   set_f1(field_holder);
 134   set_f2(field_offset);
 135   assert((field_index & field_index_mask) == field_index,


 137   set_field_flags(field_type,
 138                   ((is_volatile ? 1 : 0) << is_volatile_shift) |
 139                   ((is_final    ? 1 : 0) << is_final_shift),
 140                   field_index);
 141   set_bytecode_1(get_code);
 142   set_bytecode_2(put_code);
 143   NOT_PRODUCT(verify(tty));
 144 }
 145 
 146 void ConstantPoolCacheEntry::set_parameter_size(int value) {
 147   // This routine is called only in corner cases where the CPCE is not yet initialized.
 148   // See AbstractInterpreter::deopt_continue_after_entry.
 149   assert(_flags == 0 || parameter_size() == 0 || parameter_size() == value,
 150          "size must not change: parameter_size=%d, value=%d", parameter_size(), value);
 151   // Setting the parameter size by itself is only safe if the
 152   // current value of _flags is 0, otherwise another thread may have
 153   // updated it and we don't want to overwrite that value.  Don't
 154   // bother trying to update it once it's nonzero but always make
 155   // sure that the final parameter size agrees with what was passed.
 156   if (_flags == 0) {
 157     intx newflags = (value & parameter_size_mask);
 158     Atomic::cmpxchg(newflags, &_flags, (intx)0);
 159   }
 160   guarantee(parameter_size() == value,
 161             "size must not change: parameter_size=%d, value=%d", parameter_size(), value);
 162 }
 163 
 164 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
 165                                                        const methodHandle& method,
 166                                                        int vtable_index,
 167                                                        bool sender_is_interface) {
 168   bool is_vtable_call = (vtable_index >= 0);  // FIXME: split this method on this boolean
 169   assert(method->interpreter_entry() != NULL, "should have been set at this point");
 170   assert(!method->is_obsolete(),  "attempt to write obsolete method to cpCache");
 171 
 172   int byte_no = -1;
 173   bool change_to_virtual = false;
 174 
 175   switch (invoke_code) {
 176     case Bytecodes::_invokeinterface:
 177       // We get here from InterpreterRuntime::resolve_invoke when an invokeinterface
 178       // instruction somehow links to a non-interface method (in Object).


< prev index next >