< prev index next >

src/hotspot/share/ci/ciObjArrayKlass.cpp

Print this page
*** 20,14 ***
--- 20,16 ---
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   *
   */
  
+ #include "ci/ciFlatArrayKlass.hpp"
  #include "ci/ciInstanceKlass.hpp"
  #include "ci/ciObjArrayKlass.hpp"
  #include "ci/ciSymbol.hpp"
  #include "ci/ciUtilities.inline.hpp"
+ #include "oops/inlineKlass.inline.hpp"
  #include "oops/objArrayKlass.hpp"
  #include "runtime/signature.hpp"
  
  // ciObjArrayKlass
  //

*** 61,18 ***
  ciObjArrayKlass::ciObjArrayKlass(ciSymbol* array_name,
                                   ciKlass* base_element_klass,
                                   int dimension)
    : ciArrayKlass(array_name,
                   dimension, T_OBJECT) {
!     _base_element_klass = base_element_klass;
!     assert(_base_element_klass->is_instance_klass() ||
!            _base_element_klass->is_type_array_klass(), "bad base klass");
!     if (dimension == 1) {
!       _element_klass = base_element_klass;
!     } else {
!       _element_klass = nullptr;
!     }
  }
  
  // ------------------------------------------------------------------
  // ciObjArrayKlass::element_klass
  //
--- 63,19 ---
  ciObjArrayKlass::ciObjArrayKlass(ciSymbol* array_name,
                                   ciKlass* base_element_klass,
                                   int dimension)
    : ciArrayKlass(array_name,
                   dimension, T_OBJECT) {
!   _base_element_klass = base_element_klass;
!   assert(_base_element_klass->is_instance_klass() ||
!          _base_element_klass->is_type_array_klass() ||
!          _base_element_klass->is_flat_array_klass(), "bad base klass");
!   if (dimension == 1) {
!     _element_klass = base_element_klass;
!   } else {
!     _element_klass = nullptr;
+   }
  }
  
  // ------------------------------------------------------------------
  // ciObjArrayKlass::element_klass
  //

*** 113,11 ***
    int pos = 0;
    for ( ; pos < dimension; pos++) {
      name[pos] = JVM_SIGNATURE_ARRAY;
    }
    Symbol* base_name_sym = element_name->get_symbol();
- 
    if (Signature::is_array(base_name_sym) ||
        Signature::has_envelope(base_name_sym)) {
      strncpy(&name[pos], (char*)element_name->base(), element_len);
      name[pos + element_len] = '\0';
    } else {
--- 116,10 ---

*** 131,26 ***
  
  // ------------------------------------------------------------------
  // ciObjArrayKlass::make_impl
  //
  // Implementation of make.
! ciObjArrayKlass* ciObjArrayKlass::make_impl(ciKlass* element_klass) {
- 
    if (element_klass->is_loaded()) {
      EXCEPTION_CONTEXT;
      // The element klass is loaded
      Klass* array = element_klass->get_Klass()->array_klass(THREAD);
      if (HAS_PENDING_EXCEPTION) {
        CLEAR_PENDING_EXCEPTION;
        CURRENT_THREAD_ENV->record_out_of_memory_failure();
        return ciEnv::unloaded_ciobjarrayklass();
      }
!     return CURRENT_THREAD_ENV->get_obj_array_klass(array);
    }
  
!   // The array klass was unable to be made or the element klass was
-   // not loaded.
    ciSymbol* array_name = construct_array_name(element_klass->name(), 1);
    if (array_name == ciEnv::unloaded_cisymbol()) {
      return ciEnv::unloaded_ciobjarrayklass();
    }
    return
--- 133,40 ---
  
  // ------------------------------------------------------------------
  // ciObjArrayKlass::make_impl
  //
  // Implementation of make.
! ciArrayKlass* ciObjArrayKlass::make_impl(ciKlass* element_klass, bool vm_type, bool null_free, bool atomic) {
    if (element_klass->is_loaded()) {
      EXCEPTION_CONTEXT;
      // The element klass is loaded
      Klass* array = element_klass->get_Klass()->array_klass(THREAD);
      if (HAS_PENDING_EXCEPTION) {
        CLEAR_PENDING_EXCEPTION;
        CURRENT_THREAD_ENV->record_out_of_memory_failure();
        return ciEnv::unloaded_ciobjarrayklass();
      }
!     if (vm_type) {
+       ArrayKlass::ArrayProperties props = ArrayKlass::ArrayProperties::DEFAULT;
+       if (null_free) {
+         assert(element_klass->is_inlinetype(), "Only value class arrays can be null free");
+         props = (ArrayKlass::ArrayProperties)(props | ArrayKlass::ArrayProperties::NULL_RESTRICTED);
+       }
+       if (!atomic) {
+         assert(element_klass->is_inlinetype(), "Only value class arrays can be non-atomic");
+         props = (ArrayKlass::ArrayProperties)(props | ArrayKlass::ArrayProperties::NON_ATOMIC);
+       }
+       array = ObjArrayKlass::cast(array)->klass_with_properties(props, THREAD);
+     }
+     if (array->is_flatArray_klass()) {
+       return CURRENT_THREAD_ENV->get_flat_array_klass(array);
+     } else {
+       return CURRENT_THREAD_ENV->get_obj_array_klass(array);
+     }
    }
  
!   // The array klass was unable to be made or the element klass was not loaded.
    ciSymbol* array_name = construct_array_name(element_klass->name(), 1);
    if (array_name == ciEnv::unloaded_cisymbol()) {
      return ciEnv::unloaded_ciobjarrayklass();
    }
    return

*** 160,26 ***
  
  // ------------------------------------------------------------------
  // ciObjArrayKlass::make
  //
  // Make an array klass corresponding to the specified primitive type.
! ciObjArrayKlass* ciObjArrayKlass::make(ciKlass* element_klass) {
!   GUARDED_VM_ENTRY(return make_impl(element_klass);)
  }
  
! ciObjArrayKlass* ciObjArrayKlass::make(ciKlass* element_klass, int dims) {
    ciKlass* klass = element_klass;
    for (int i = 0; i < dims; i++) {
!     klass = ciObjArrayKlass::make(klass);
    }
!   return klass->as_obj_array_klass();
  }
  
  ciKlass* ciObjArrayKlass::exact_klass() {
    ciType* base = base_element_type();
    if (base->is_instance_klass()) {
      ciInstanceKlass* ik = base->as_instance_klass();
      if (ik->exact_klass() != nullptr) {
        return this;
      }
    } else if (base->is_primitive_type()) {
      return this;
--- 176,34 ---
  
  // ------------------------------------------------------------------
  // ciObjArrayKlass::make
  //
  // Make an array klass corresponding to the specified primitive type.
! ciArrayKlass* ciObjArrayKlass::make(ciKlass* element_klass, bool vm_type, bool null_free, bool atomic) {
!   GUARDED_VM_ENTRY(return make_impl(element_klass, vm_type, null_free, atomic);)
  }
  
! ciArrayKlass* ciObjArrayKlass::make(ciKlass* element_klass, int dims) {
    ciKlass* klass = element_klass;
    for (int i = 0; i < dims; i++) {
!     klass = ciObjArrayKlass::make(klass, /* vm_type = */ false);
    }
!   return klass->as_array_klass();
  }
  
  ciKlass* ciObjArrayKlass::exact_klass() {
+   if (!is_loaded()) {
+     return nullptr;
+   }
    ciType* base = base_element_type();
    if (base->is_instance_klass()) {
      ciInstanceKlass* ik = base->as_instance_klass();
+     // Even though MyValue is final, [LMyValue is only exact if the array
+     // is null-free due to null-free [LMyValue <: null-able [LMyValue.
+     if (ik->is_inlinetype() && !is_elem_null_free()) {
+       return nullptr;
+     }
      if (ik->exact_klass() != nullptr) {
        return this;
      }
    } else if (base->is_primitive_type()) {
      return this;
< prev index next >