changeset 9129:9efdbe72ed1d

8231430: C2: Memory stomp in max_array_length() for T_ILLEGAL type Reviewed-by: kvn, thartmann
author vlivanov
date Tue, 03 Dec 2019 20:13:16 +0300
parents e314de338c65
children 2e636385f137
files src/share/vm/opto/type.cpp src/share/vm/opto/type.hpp src/share/vm/utilities/globalDefinitions.hpp
diffstat 3 files changed, 19 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/type.cpp	Thu Feb 20 06:28:18 2020 +0000
+++ b/src/share/vm/opto/type.cpp	Tue Dec 03 20:13:16 2019 +0300
@@ -3753,29 +3753,22 @@
   return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id, _speculative, _inline_depth);
 }
 
-//-----------------------------narrow_size_type-------------------------------
-// Local cache for arrayOopDesc::max_array_length(etype),
-// which is kind of slow (and cached elsewhere by other users).
-static jint max_array_length_cache[T_CONFLICT+1];
-static jint max_array_length(BasicType etype) {
-  jint& cache = max_array_length_cache[etype];
-  jint res = cache;
-  if (res == 0) {
-    switch (etype) {
-    case T_NARROWOOP:
+//-----------------------------max_array_length-------------------------------
+// A wrapper around arrayOopDesc::max_array_length(etype) with some input normalization.
+jint TypeAryPtr::max_array_length(BasicType etype) {
+  if (!is_java_primitive(etype) && !is_reference_type(etype)) {
+    if (etype == T_NARROWOOP) {
       etype = T_OBJECT;
-      break;
-    case T_NARROWKLASS:
-    case T_CONFLICT:
-    case T_ILLEGAL:
-    case T_VOID:
-      etype = T_BYTE;           // will produce conservatively high value
+    } else if (etype == T_ILLEGAL) { // bottom[]
+      etype = T_BYTE; // will produce conservatively high value
+    } else {
+      fatal(err_msg("not an element type: %s", type2name(etype)));
     }
-    cache = res = arrayOopDesc::max_array_length(etype);
   }
-  return res;
-}
-
+  return arrayOopDesc::max_array_length(etype);
+}
+
+//-----------------------------narrow_size_type-------------------------------
 // Narrow the given size type to the index range for the given array base type.
 // Return NULL if the resulting int type becomes empty.
 const TypeInt* TypeAryPtr::narrow_size_type(const TypeInt* size) const {
--- a/src/share/vm/opto/type.hpp	Thu Feb 20 06:28:18 2020 +0000
+++ b/src/share/vm/opto/type.hpp	Tue Dec 03 20:13:16 2019 +0300
@@ -433,7 +433,6 @@
 
 private:
   // support arrays
-  static const BasicType _basic_type[];
   static const Type*        _zero_type[T_CONFLICT+1];
   static const Type* _const_basic_type[T_CONFLICT+1];
 };
@@ -1154,6 +1153,8 @@
   const TypeAryPtr* cast_to_stable(bool stable, int stable_dimension = 1) const;
   int stable_dimension() const;
 
+  static jint max_array_length(BasicType etype) ;
+
   // Convenience common pre-built types.
   static const TypeAryPtr *RANGE;
   static const TypeAryPtr *OOPS;
--- a/src/share/vm/utilities/globalDefinitions.hpp	Thu Feb 20 06:28:18 2020 +0000
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Tue Dec 03 20:13:16 2019 +0300
@@ -644,6 +644,10 @@
   return (t == T_BYTE || t == T_SHORT);
 }
 
+inline bool is_reference_type(BasicType t) {
+  return (t == T_OBJECT || t == T_ARRAY);
+}
+
 // Convert a char from a classfile signature to a BasicType
 inline BasicType char2type(char c) {
   switch( c ) {