< prev index next >

src/hotspot/share/interpreter/interpreterRuntime.cpp

Print this page
*** 24,10 ***
--- 24,11 ---
  
  #include "precompiled.hpp"
  #include "jvm_io.h"
  #include "classfile/javaClasses.inline.hpp"
  #include "classfile/symbolTable.hpp"
+ #include "classfile/systemDictionary.hpp"
  #include "classfile/vmClasses.hpp"
  #include "classfile/vmSymbols.hpp"
  #include "code/codeCache.hpp"
  #include "compiler/compilationPolicy.hpp"
  #include "compiler/compileBroker.hpp"

*** 42,10 ***
--- 43,13 ---
  #include "memory/oopFactory.hpp"
  #include "memory/resourceArea.hpp"
  #include "memory/universe.hpp"
  #include "oops/constantPool.hpp"
  #include "oops/cpCache.inline.hpp"
+ #include "oops/flatArrayKlass.hpp"
+ #include "oops/flatArrayOop.inline.hpp"
+ #include "oops/inlineKlass.inline.hpp"
  #include "oops/instanceKlass.inline.hpp"
  #include "oops/klass.inline.hpp"
  #include "oops/methodData.hpp"
  #include "oops/objArrayKlass.hpp"
  #include "oops/objArrayOop.inline.hpp"

*** 71,10 ***
--- 75,11 ---
  #include "runtime/synchronizer.hpp"
  #include "runtime/threadCritical.hpp"
  #include "utilities/align.hpp"
  #include "utilities/copy.hpp"
  #include "utilities/events.hpp"
+ #include "utilities/globalDefinitions.hpp"
  #ifdef COMPILER2
  #include "opto/runtime.hpp"
  #endif
  
  // Helper class to access current interpreter state

*** 152,11 ***
    int index = wide ? last_frame.get_index_u2(Bytecodes::_ldc_w) : last_frame.get_index_u1(Bytecodes::_ldc);
    constantTag tag = pool->tag_at(index);
  
    assert (tag.is_unresolved_klass() || tag.is_klass(), "wrong ldc call");
    Klass* klass = pool->klass_at(index, CHECK);
!   oop java_class = klass->java_mirror();
    current->set_vm_result(java_class);
  JRT_END
  
  JRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* current, Bytecodes::Code bytecode)) {
    assert(bytecode == Bytecodes::_ldc ||
--- 157,13 ---
    int index = wide ? last_frame.get_index_u2(Bytecodes::_ldc_w) : last_frame.get_index_u1(Bytecodes::_ldc);
    constantTag tag = pool->tag_at(index);
  
    assert (tag.is_unresolved_klass() || tag.is_klass(), "wrong ldc call");
    Klass* klass = pool->klass_at(index, CHECK);
!   oop java_class = tag.is_Qdescriptor_klass()
+                       ? InlineKlass::cast(klass)->val_mirror()
+                       : klass->java_mirror();
    current->set_vm_result(java_class);
  JRT_END
  
  JRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* current, Bytecodes::Code bytecode)) {
    assert(bytecode == Bytecodes::_ldc ||

*** 216,10 ***
--- 223,14 ---
  
  JRT_ENTRY(void, InterpreterRuntime::_new(JavaThread* current, ConstantPool* pool, int index))
    Klass* k = pool->klass_at(index, CHECK);
    InstanceKlass* klass = InstanceKlass::cast(k);
  
+   if (klass->is_inline_klass()) {
+     THROW(vmSymbols::java_lang_InstantiationError());
+   }
+ 
    // Make sure we are not instantiating an abstract klass
    klass->check_valid_for_instantiation(true, CHECK);
  
    // Make sure klass is initialized
    klass->initialize(CHECK);

*** 240,34 ***
    //       because the _breakpoint bytecode would be lost.
    oop obj = klass->allocate_instance(CHECK);
    current->set_vm_result(obj);
  JRT_END
  
  
  JRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* current, BasicType type, jint size))
    oop obj = oopFactory::new_typeArray(type, size, CHECK);
    current->set_vm_result(obj);
  JRT_END
  
  
  JRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* current, ConstantPool* pool, int index, jint size))
    Klass*    klass = pool->klass_at(index, CHECK);
!   objArrayOop obj = oopFactory::new_objArray(klass, size, CHECK);
    current->set_vm_result(obj);
  JRT_END
  
  
  JRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* current, jint* first_size_address))
    // We may want to pass in more arguments - could make this slightly faster
    LastFrameAccessor last_frame(current);
    ConstantPool* constants = last_frame.method()->constants();
!   int          i = last_frame.get_index_u2(Bytecodes::_multianewarray);
!   Klass* klass   = constants->klass_at(i, CHECK);
    int   nof_dims = last_frame.number_of_dimensions();
    assert(klass->is_klass(), "not a class");
    assert(nof_dims >= 1, "multianewarray rank must be nonzero");
  
    // We must create an array of jints to pass to multi_allocate.
    ResourceMark rm(current);
    const int small_dims = 10;
    jint dim_array[small_dims];
    jint *dims = &dim_array[0];
--- 251,210 ---
    //       because the _breakpoint bytecode would be lost.
    oop obj = klass->allocate_instance(CHECK);
    current->set_vm_result(obj);
  JRT_END
  
+ JRT_ENTRY(void, InterpreterRuntime::defaultvalue(JavaThread* current, ConstantPool* pool, int index))
+   // Getting the InlineKlass
+   Klass* k = pool->klass_at(index, CHECK);
+   if (!k->is_inline_klass()) {
+     // inconsistency with 'new' which throws an InstantiationError
+     // in the future, defaultvalue will just return null instead of throwing an exception
+     THROW(vmSymbols::java_lang_IncompatibleClassChangeError());
+   }
+   assert(k->is_inline_klass(), "defaultvalue argument must be the inline type class");
+   InlineKlass* vklass = InlineKlass::cast(k);
+ 
+   vklass->initialize(CHECK);
+   oop res = vklass->default_value();
+   current->set_vm_result(res);
+ JRT_END
+ 
+ JRT_ENTRY(int, InterpreterRuntime::withfield(JavaThread* current, ConstantPoolCacheEntry* cpe, uintptr_t ptr))
+   oop obj = NULL;
+   int recv_offset = type2size[as_BasicType(cpe->flag_state())];
+   assert(frame::interpreter_frame_expression_stack_direction() == -1, "currently is -1 on all platforms");
+   int ret_adj = (recv_offset + type2size[T_OBJECT] )* AbstractInterpreter::stackElementSize;
+   obj = (oopDesc*)(((uintptr_t*)ptr)[recv_offset * Interpreter::stackElementWords]);
+   if (obj == NULL) {
+     THROW_(vmSymbols::java_lang_NullPointerException(), ret_adj);
+   }
+   assert(oopDesc::is_oop(obj), "Verifying receiver");
+   assert(obj->klass()->is_inline_klass(), "Must have been checked during resolution");
+   instanceHandle old_value_h(THREAD, (instanceOop)obj);
+   oop ref = NULL;
+   if (cpe->flag_state() == atos) {
+     ref = *(oopDesc**)ptr;
+   }
+   Handle ref_h(THREAD, ref);
+   InlineKlass* ik = InlineKlass::cast(old_value_h()->klass());
+   instanceOop new_value = ik->allocate_instance_buffer(CHECK_(ret_adj));
+   Handle new_value_h = Handle(THREAD, new_value);
+   ik->inline_copy_oop_to_new_oop(old_value_h(), new_value_h());
+   int offset = cpe->f2_as_offset();
+   switch(cpe->flag_state()) {
+     case ztos:
+       new_value_h()->bool_field_put(offset, (jboolean)(*(jint*)ptr));
+       break;
+     case btos:
+       new_value_h()->byte_field_put(offset, (jbyte)(*(jint*)ptr));
+       break;
+     case ctos:
+       new_value_h()->char_field_put(offset, (jchar)(*(jint*)ptr));
+       break;
+     case stos:
+       new_value_h()->short_field_put(offset, (jshort)(*(jint*)ptr));
+       break;
+     case itos:
+       new_value_h()->int_field_put(offset, (*(jint*)ptr));
+       break;
+     case ltos:
+       new_value_h()->long_field_put(offset, *(jlong*)ptr);
+       break;
+     case ftos:
+       new_value_h()->float_field_put(offset, *(jfloat*)ptr);
+       break;
+     case dtos:
+       new_value_h()->double_field_put(offset, *(jdouble*)ptr);
+       break;
+     case atos:
+       {
+         if (cpe->is_null_free_inline_type())  {
+           if (!cpe->is_inlined()) {
+               if (ref_h() == NULL) {
+                 THROW_(vmSymbols::java_lang_NullPointerException(), ret_adj);
+               }
+               new_value_h()->obj_field_put(offset, ref_h());
+             } else {
+               int field_index = cpe->field_index();
+               InlineKlass* field_ik = InlineKlass::cast(ik->get_inline_type_field_klass(field_index));
+               field_ik->write_inlined_field(new_value_h(), offset, ref_h(), CHECK_(ret_adj));
+             }
+         } else {
+           new_value_h()->obj_field_put(offset, ref_h());
+         }
+       }
+       break;
+     default:
+       ShouldNotReachHere();
+   }
+   current->set_vm_result(new_value_h());
+   return ret_adj;
+ JRT_END
+ 
+ JRT_ENTRY(void, InterpreterRuntime::uninitialized_static_inline_type_field(JavaThread* current, oopDesc* mirror, int index))
+   // The interpreter tries to access an inline static field that has not been initialized.
+   // This situation can happen in different scenarios:
+   //   1 - if the load or initialization of the field failed during step 8 of
+   //       the initialization of the holder of the field, in this case the access to the field
+   //       must fail
+   //   2 - it can also happen when the initialization of the holder class triggered the initialization of
+   //       another class which accesses this field in its static initializer, in this case the
+   //       access must succeed to allow circularity
+   // The code below tries to load and initialize the field's class again before returning the default value.
+   // If the field was not initialized because of an error, a exception should be thrown.
+   // If the class is being initialized, the default value is returned.
+   instanceHandle mirror_h(THREAD, (instanceOop)mirror);
+   InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
+   assert(klass->field_signature(index)->is_Q_signature(), "Sanity check");
+   if (klass->is_being_initialized() && klass->is_reentrant_initialization(THREAD)) {
+     int offset = klass->field_offset(index);
+     Klass* field_k = klass->get_inline_type_field_klass_or_null(index);
+     if (field_k == NULL) {
+       field_k = SystemDictionary::resolve_or_fail(klass->field_signature(index)->fundamental_name(THREAD),
+           Handle(THREAD, klass->class_loader()),
+           Handle(THREAD, klass->protection_domain()),
+           true, CHECK);
+       assert(field_k != NULL, "Should have been loaded or an exception thrown above");
+       klass->set_inline_type_field_klass(index, field_k);
+     }
+     field_k->initialize(CHECK);
+     oop defaultvalue = InlineKlass::cast(field_k)->default_value();
+     // It is safe to initialized the static field because 1) the current thread is the initializing thread
+     // and is the only one that can access it, and 2) the field is actually not initialized (i.e. null)
+     // otherwise the JVM should not be executing this code.
+     mirror->obj_field_put(offset, defaultvalue);
+     current->set_vm_result(defaultvalue);
+   } else {
+     assert(klass->is_in_error_state(), "If not initializing, initialization must have failed to get there");
+     ResourceMark rm(THREAD);
+     const char* desc = "Could not initialize class ";
+     const char* className = klass->external_name();
+     size_t msglen = strlen(desc) + strlen(className) + 1;
+     char* message = NEW_RESOURCE_ARRAY(char, msglen);
+     if (NULL == message) {
+       // Out of memory: can't create detailed error message
+       THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), className);
+     } else {
+       jio_snprintf(message, msglen, "%s%s", desc, className);
+       THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), message);
+     }
+   }
+ JRT_END
+ 
+ JRT_ENTRY(void, InterpreterRuntime::read_inlined_field(JavaThread* current, oopDesc* obj, int index, Klass* field_holder))
+   Handle obj_h(THREAD, obj);
+ 
+   assert(oopDesc::is_oop(obj), "Sanity check");
+ 
+   assert(field_holder->is_instance_klass(), "Sanity check");
+   InstanceKlass* klass = InstanceKlass::cast(field_holder);
+ 
+   assert(klass->field_is_inlined(index), "Sanity check");
+ 
+   InlineKlass* field_vklass = InlineKlass::cast(klass->get_inline_type_field_klass(index));
+   assert(field_vklass->is_initialized(), "Must be initialized at this point");
+ 
+   oop res = field_vklass->read_inlined_field(obj_h(), klass->field_offset(index), CHECK);
+   current->set_vm_result(res);
+ JRT_END
  
  JRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* current, BasicType type, jint size))
    oop obj = oopFactory::new_typeArray(type, size, CHECK);
    current->set_vm_result(obj);
  JRT_END
  
  
  JRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* current, ConstantPool* pool, int index, jint size))
    Klass*    klass = pool->klass_at(index, CHECK);
!   bool      is_qtype_desc = pool->tag_at(index).is_Qdescriptor_klass();
+   arrayOop obj;
+   if ((!klass->is_array_klass()) && is_qtype_desc) { // Logically creates elements, ensure klass init
+     klass->initialize(CHECK);
+     obj = oopFactory::new_flatArray(klass, size, CHECK);
+   } else {
+     obj = oopFactory::new_objArray(klass, size, CHECK);
+   }
    current->set_vm_result(obj);
  JRT_END
  
+ JRT_ENTRY(void, InterpreterRuntime::value_array_load(JavaThread* current, arrayOopDesc* array, int index))
+   flatArrayHandle vah(current, (flatArrayOop)array);
+   oop value_holder = flatArrayOopDesc::value_alloc_copy_from_index(vah, index, CHECK);
+   current->set_vm_result(value_holder);
+ JRT_END
+ 
+ JRT_ENTRY(void, InterpreterRuntime::value_array_store(JavaThread* current, void* val, arrayOopDesc* array, int index))
+   assert(val != NULL, "can't store null into flat array");
+   ((flatArrayOop)array)->value_copy_to_index(cast_to_oop(val), index);
+ JRT_END
  
  JRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* current, jint* first_size_address))
    // We may want to pass in more arguments - could make this slightly faster
    LastFrameAccessor last_frame(current);
    ConstantPool* constants = last_frame.method()->constants();
!   int i = last_frame.get_index_u2(Bytecodes::_multianewarray);
!   Klass* klass = constants->klass_at(i, CHECK);
+   bool is_qtype = klass->name()->is_Q_array_signature();
    int   nof_dims = last_frame.number_of_dimensions();
    assert(klass->is_klass(), "not a class");
    assert(nof_dims >= 1, "multianewarray rank must be nonzero");
  
+   if (is_qtype) { // Logically creates elements, ensure klass init
+     klass->initialize(CHECK);
+   }
+ 
    // We must create an array of jints to pass to multi_allocate.
    ResourceMark rm(current);
    const int small_dims = 10;
    jint dim_array[small_dims];
    jint *dims = &dim_array[0];

*** 288,10 ***
--- 475,33 ---
    assert(oopDesc::is_oop(obj), "must be a valid oop");
    assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
    InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
  JRT_END
  
+ JRT_ENTRY(jboolean, InterpreterRuntime::is_substitutable(JavaThread* current, oopDesc* aobj, oopDesc* bobj))
+   assert(oopDesc::is_oop(aobj) && oopDesc::is_oop(bobj), "must be valid oops");
+ 
+   Handle ha(THREAD, aobj);
+   Handle hb(THREAD, bobj);
+   JavaValue result(T_BOOLEAN);
+   JavaCallArguments args;
+   args.push_oop(ha);
+   args.push_oop(hb);
+   methodHandle method(current, Universe::is_substitutable_method());
+   JavaCalls::call(&result, method, &args, THREAD);
+   if (HAS_PENDING_EXCEPTION) {
+     // Something really bad happened because isSubstitutable() should not throw exceptions
+     // If it is an error, just let it propagate
+     // If it is an exception, wrap it into an InternalError
+     if (!PENDING_EXCEPTION->is_a(vmClasses::Error_klass())) {
+       Handle e(THREAD, PENDING_EXCEPTION);
+       CLEAR_PENDING_EXCEPTION;
+       THROW_MSG_CAUSE_(vmSymbols::java_lang_InternalError(), "Internal error in substitutability test", e, false);
+     }
+   }
+   return result.get_jboolean();
+ JRT_END
  
  // Quicken instance-of and check-cast bytecodes
  JRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* current))
    // Force resolving; quicken the bytecode
    LastFrameAccessor last_frame(current);

*** 614,10 ***
--- 824,14 ---
    ResourceMark rm(current);
    methodHandle mh = methodHandle(current, missingMethod);
    LinkResolver::throw_abstract_method_error(mh, recvKlass, THREAD);
  JRT_END
  
+ JRT_ENTRY(void, InterpreterRuntime::throw_InstantiationError(JavaThread* current))
+   THROW(vmSymbols::java_lang_InstantiationError());
+ JRT_END
+ 
  
  JRT_ENTRY(void, InterpreterRuntime::throw_IncompatibleClassChangeError(JavaThread* current))
    THROW(vmSymbols::java_lang_IncompatibleClassChangeError());
  JRT_END
  

*** 647,12 ***
    fieldDescriptor info;
    LastFrameAccessor last_frame(current);
    constantPoolHandle pool(current, last_frame.method()->constants());
    methodHandle m(current, last_frame.method());
    bool is_put    = (bytecode == Bytecodes::_putfield  || bytecode == Bytecodes::_nofast_putfield ||
!                     bytecode == Bytecodes::_putstatic);
    bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
  
    {
      JvmtiHideSingleStepping jhss(current);
      JavaThread* THREAD = current; // For exception macros.
      LinkResolver::resolve_field_access(info, pool, last_frame.get_index_u2_cpcache(bytecode),
--- 861,13 ---
    fieldDescriptor info;
    LastFrameAccessor last_frame(current);
    constantPoolHandle pool(current, last_frame.method()->constants());
    methodHandle m(current, last_frame.method());
    bool is_put    = (bytecode == Bytecodes::_putfield  || bytecode == Bytecodes::_nofast_putfield ||
!                     bytecode == Bytecodes::_putstatic || bytecode == Bytecodes::_withfield);
    bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
+   bool is_inline_type  = bytecode == Bytecodes::_withfield;
  
    {
      JvmtiHideSingleStepping jhss(current);
      JavaThread* THREAD = current; // For exception macros.
      LinkResolver::resolve_field_access(info, pool, last_frame.get_index_u2_cpcache(bytecode),

*** 693,13 ***
    assert(!(has_initialized_final_update && !info.access_flags().is_final()), "Fields with initialized final updates must be final");
  
    Bytecodes::Code get_code = (Bytecodes::Code)0;
    Bytecodes::Code put_code = (Bytecodes::Code)0;
    if (!uninitialized_static) {
!     get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield);
!     if ((is_put && !has_initialized_final_update) || !info.access_flags().is_final()) {
!       put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
      }
    }
  
    cp_cache_entry->set_field(
      get_code,
--- 908,19 ---
    assert(!(has_initialized_final_update && !info.access_flags().is_final()), "Fields with initialized final updates must be final");
  
    Bytecodes::Code get_code = (Bytecodes::Code)0;
    Bytecodes::Code put_code = (Bytecodes::Code)0;
    if (!uninitialized_static) {
!     if (is_static) {
!       get_code = Bytecodes::_getstatic;
!     } else {
+       get_code = Bytecodes::_getfield;
+     }
+     if (is_put && is_inline_type) {
+         put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_withfield);
+     } else if ((is_put && !has_initialized_final_update) || !info.access_flags().is_final()) {
+         put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
      }
    }
  
    cp_cache_entry->set_field(
      get_code,

*** 707,11 ***
      info.field_holder(),
      info.index(),
      info.offset(),
      state,
      info.access_flags().is_final(),
!     info.access_flags().is_volatile()
    );
  }
  
  
  //------------------------------------------------------------------------------------------------------------------------
--- 928,13 ---
      info.field_holder(),
      info.index(),
      info.offset(),
      state,
      info.access_flags().is_final(),
!     info.access_flags().is_volatile(),
+     info.is_inlined(),
+     info.signature()->is_Q_signature() && info.is_inline_type()
    );
  }
  
  
  //------------------------------------------------------------------------------------------------------------------------

*** 939,10 ***
--- 1162,11 ---
    switch (bytecode) {
    case Bytecodes::_getstatic:
    case Bytecodes::_putstatic:
    case Bytecodes::_getfield:
    case Bytecodes::_putfield:
+   case Bytecodes::_withfield:
      resolve_get_put(current, bytecode);
      break;
    case Bytecodes::_invokevirtual:
    case Bytecodes::_invokespecial:
    case Bytecodes::_invokestatic:

*** 1136,19 ***
    InstanceKlass* ik = InstanceKlass::cast(cp_entry->f1_as_klass());
    int index = cp_entry->field_index();
    if ((ik->field_access_flags(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return;
  
    bool is_static = (obj == NULL);
    HandleMark hm(current);
  
    Handle h_obj;
    if (!is_static) {
      // non-static field accessors have an object, but we need a handle
      h_obj = Handle(current, obj);
    }
    InstanceKlass* cp_entry_f1 = InstanceKlass::cast(cp_entry->f1_as_klass());
!   jfieldID fid = jfieldIDWorkaround::to_jfieldID(cp_entry_f1, cp_entry->f2_as_index(), is_static);
    LastFrameAccessor last_frame(current);
    JvmtiExport::post_field_access(current, last_frame.method(), last_frame.bcp(), cp_entry_f1, h_obj, fid);
  JRT_END
  
  JRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread* current, oopDesc* obj,
--- 1360,20 ---
    InstanceKlass* ik = InstanceKlass::cast(cp_entry->f1_as_klass());
    int index = cp_entry->field_index();
    if ((ik->field_access_flags(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return;
  
    bool is_static = (obj == NULL);
+   bool is_inlined = cp_entry->is_inlined();
    HandleMark hm(current);
  
    Handle h_obj;
    if (!is_static) {
      // non-static field accessors have an object, but we need a handle
      h_obj = Handle(current, obj);
    }
    InstanceKlass* cp_entry_f1 = InstanceKlass::cast(cp_entry->f1_as_klass());
!   jfieldID fid = jfieldIDWorkaround::to_jfieldID(cp_entry_f1, cp_entry->f2_as_index(), is_static, is_inlined);
    LastFrameAccessor last_frame(current);
    JvmtiExport::post_field_access(current, last_frame.method(), last_frame.bcp(), cp_entry_f1, h_obj, fid);
  JRT_END
  
  JRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread* current, oopDesc* obj,

*** 1174,14 ***
      case atos: sig_type = JVM_SIGNATURE_CLASS;   break;
      case ltos: sig_type = JVM_SIGNATURE_LONG;    break;
      case dtos: sig_type = JVM_SIGNATURE_DOUBLE;  break;
      default:  ShouldNotReachHere(); return;
    }
    bool is_static = (obj == NULL);
  
    HandleMark hm(current);
!   jfieldID fid = jfieldIDWorkaround::to_jfieldID(ik, cp_entry->f2_as_index(), is_static);
    jvalue fvalue;
  #ifdef _LP64
    fvalue = *value;
  #else
    // Long/double values are stored unaligned and also noncontiguously with
--- 1399,21 ---
      case atos: sig_type = JVM_SIGNATURE_CLASS;   break;
      case ltos: sig_type = JVM_SIGNATURE_LONG;    break;
      case dtos: sig_type = JVM_SIGNATURE_DOUBLE;  break;
      default:  ShouldNotReachHere(); return;
    }
+ 
+   // Both Q-signatures and L-signatures are mapped to atos
+   if (cp_entry->flag_state() == atos && ik->field_signature(index)->is_Q_signature()) {
+     sig_type = JVM_SIGNATURE_INLINE_TYPE;
+   }
+ 
    bool is_static = (obj == NULL);
+   bool is_inlined = cp_entry->is_inlined();
  
    HandleMark hm(current);
!   jfieldID fid = jfieldIDWorkaround::to_jfieldID(ik, cp_entry->f2_as_index(), is_static, is_inlined);
    jvalue fvalue;
  #ifdef _LP64
    fvalue = *value;
  #else
    // Long/double values are stored unaligned and also noncontiguously with
< prev index next >