src/share/vm/interpreter/interpreterRuntime.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8163880 Sdiff src/share/vm/interpreter

src/share/vm/interpreter/interpreterRuntime.cpp

Print this page




 559   fieldDescriptor info;
 560   constantPoolHandle pool(thread, method(thread)->constants());
 561   methodHandle m(thread, method(thread));
 562   bool is_put    = (bytecode == Bytecodes::_putfield  || bytecode == Bytecodes::_nofast_putfield ||
 563                     bytecode == Bytecodes::_putstatic);
 564   bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
 565 
 566   {
 567     JvmtiHideSingleStepping jhss(thread);
 568     LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode),
 569                                        m, bytecode, CHECK);
 570   } // end JvmtiHideSingleStepping
 571 
 572   // check if link resolution caused cpCache to be updated
 573   ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
 574   if (cp_cache_entry->is_resolved(bytecode)) return;
 575 
 576   // compute auxiliary field attributes
 577   TosState state  = as_TosState(info.field_type());
 578 
 579   // Put instructions on final fields are not resolved. This is required so we throw
 580   // exceptions at the correct place (when the instruction is actually invoked).
 581   // If we do not resolve an instruction in the current pass, leaving the put_code
 582   // set to zero will cause the next put instruction to the same field to reresolve.











 583   //
 584   // Also, we need to delay resolving getstatic and putstatic instructions until the
 585   // class is initialized.  This is required so that access to the static
 586   // field will call the initialization function every time until the class
 587   // is completely initialized ala. in 2.17.5 in JVM Specification.
 588   InstanceKlass* klass = InstanceKlass::cast(info.field_holder());
 589   bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) &&
 590                                !klass->is_initialized());
 591 
 592   Bytecodes::Code put_code = (Bytecodes::Code)0;
 593   if (is_put && !info.access_flags().is_final() && !uninitialized_static) {








 594     put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);

 595   }
 596 
 597   Bytecodes::Code get_code = (Bytecodes::Code)0;
 598   if (!uninitialized_static) {
 599     get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield);
 600   }
 601 
 602   cp_cache_entry->set_field(
 603     get_code,
 604     put_code,
 605     info.field_holder(),
 606     info.index(),
 607     info.offset(),
 608     state,
 609     info.access_flags().is_final(),
 610     info.access_flags().is_volatile(),
 611     pool->pool_holder()
 612   );
 613 }
 614 




 559   fieldDescriptor info;
 560   constantPoolHandle pool(thread, method(thread)->constants());
 561   methodHandle m(thread, method(thread));
 562   bool is_put    = (bytecode == Bytecodes::_putfield  || bytecode == Bytecodes::_nofast_putfield ||
 563                     bytecode == Bytecodes::_putstatic);
 564   bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
 565 
 566   {
 567     JvmtiHideSingleStepping jhss(thread);
 568     LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode),
 569                                        m, bytecode, CHECK);
 570   } // end JvmtiHideSingleStepping
 571 
 572   // check if link resolution caused cpCache to be updated
 573   ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
 574   if (cp_cache_entry->is_resolved(bytecode)) return;
 575 
 576   // compute auxiliary field attributes
 577   TosState state  = as_TosState(info.field_type());
 578 
 579   // Resolution of put instructions on final fields is delayed. That is required so that
 580   // exceptions are thrown at the correct place (when the instruction is actually invoked).
 581   // If we do not resolve an instruction in the current pass, leaving the put_code
 582   // set to zero will cause the next put instruction to the same field to reresolve.
 583 
 584   // Resolution of put instructions to final instance fields with invalid updates (i.e.,
 585   // to final instance fields with updates originating from a method different than <init>)
 586   // is inhibited. A putfield instruction targeting an instance final field must throw
 587   // an IllegalAccessError if the instruction is not in an instance
 588   // initializer method <init>. If resolution were not inhibited, a putfield
 589   // in an initializer method could be resolved in the initializer. Subsequent
 590   // putfield instructions to the same field would then use cached information.
 591   // As a result, those instructions would not pass through the VM. That is,
 592   // checks in resolve_field_access() would not be executed for those instructions
 593   // and the required IllegalAccessError would not not be thrown.
 594   //
 595   // Also, we need to delay resolving getstatic and putstatic instructions until the
 596   // class is initialized.  This is required so that access to the static
 597   // field will call the initialization function every time until the class
 598   // is completely initialized ala. in 2.17.5 in JVM Specification.
 599   InstanceKlass* klass = InstanceKlass::cast(info.field_holder());
 600   bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) &&
 601                                !klass->is_initialized());
 602 
 603   Bytecodes::Code put_code = (Bytecodes::Code)0;
 604   bool has_initialized_final_update = info.field_holder()->major_version() >= 53 &&
 605                                       info.has_initialized_final_update();
 606 
 607   if (has_initialized_final_update) {
 608     assert(info.access_flags().is_final(), "Fields with initialized final updates must be final");
 609   }
 610 
 611   if (!uninitialized_static) {
 612     if ((is_put && !has_initialized_final_update) || !info.access_flags().is_final()) {
 613       put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
 614     }
 615   }
 616 
 617   Bytecodes::Code get_code = (Bytecodes::Code)0;
 618   if (!uninitialized_static) {
 619     get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield);
 620   }
 621 
 622   cp_cache_entry->set_field(
 623     get_code,
 624     put_code,
 625     info.field_holder(),
 626     info.index(),
 627     info.offset(),
 628     state,
 629     info.access_flags().is_final(),
 630     info.access_flags().is_volatile(),
 631     pool->pool_holder()
 632   );
 633 }
 634 


src/share/vm/interpreter/interpreterRuntime.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File