< prev index next >

src/hotspot/share/opto/type.cpp

Print this page




  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "ci/ciMethodData.hpp"
  27 #include "ci/ciTypeFlow.hpp"
  28 #include "classfile/symbolTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "compiler/compileLog.hpp"
  31 #include "libadt/dict.hpp"
  32 #include "memory/oopFactory.hpp"
  33 #include "memory/resourceArea.hpp"
  34 #include "oops/instanceKlass.hpp"
  35 #include "oops/instanceMirrorKlass.hpp"
  36 #include "oops/objArrayKlass.hpp"
  37 #include "oops/typeArrayKlass.hpp"
  38 #include "opto/matcher.hpp"
  39 #include "opto/node.hpp"
  40 #include "opto/opcodes.hpp"
  41 #include "opto/type.hpp"




  42 
  43 // Portions of code courtesy of Clifford Click
  44 
  45 // Optimization - Graph Style
  46 
  47 // Dictionary of types shared among compilations.
  48 Dict* Type::_shared_type_dict = NULL;
  49 
  50 // Array which maps compiler types to Basic Types
  51 const Type::TypeInfo Type::_type_info[Type::lastype] = {
  52   { Bad,             T_ILLEGAL,    "bad",           false, Node::NotAMachineReg, relocInfo::none          },  // Bad
  53   { Control,         T_ILLEGAL,    "control",       false, 0,                    relocInfo::none          },  // Control
  54   { Bottom,          T_VOID,       "top",           false, 0,                    relocInfo::none          },  // Top
  55   { Bad,             T_INT,        "int:",          false, Op_RegI,              relocInfo::none          },  // Int
  56   { Bad,             T_LONG,       "long:",         false, Op_RegL,              relocInfo::none          },  // Long
  57   { Half,            T_VOID,       "half",          false, 0,                    relocInfo::none          },  // Half
  58   { Bad,             T_NARROWOOP,  "narrowoop:",    false, Op_RegN,              relocInfo::none          },  // NarrowOop
  59   { Bad,             T_NARROWKLASS,"narrowklass:",  false, Op_RegN,              relocInfo::none          },  // NarrowKlass
  60   { Bad,             T_ILLEGAL,    "tuple:",        false, Node::NotAMachineReg, relocInfo::none          },  // Tuple
  61   { Bad,             T_ARRAY,      "array:",        false, Node::NotAMachineReg, relocInfo::none          },  // Array


2946 const TypeOopPtr *TypeOopPtr::BOTTOM;
2947 
2948 //------------------------------TypeOopPtr-------------------------------------
2949 TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset,
2950                        int instance_id, const TypePtr* speculative, int inline_depth)
2951   : TypePtr(t, ptr, offset, speculative, inline_depth),
2952     _const_oop(o), _klass(k),
2953     _klass_is_exact(xk),
2954     _is_ptr_to_narrowoop(false),
2955     _is_ptr_to_narrowklass(false),
2956     _is_ptr_to_boxed_value(false),
2957     _instance_id(instance_id) {
2958   if (Compile::current()->eliminate_boxing() && (t == InstPtr) &&
2959       (offset > 0) && xk && (k != 0) && k->is_instance_klass()) {
2960     _is_ptr_to_boxed_value = k->as_instance_klass()->is_boxed_value_offset(offset);
2961   }
2962 #ifdef _LP64
2963   if (_offset != 0) {
2964     if (_offset == oopDesc::klass_offset_in_bytes()) {
2965       _is_ptr_to_narrowklass = UseCompressedClassPointers;




2966     } else if (klass() == NULL) {
2967       // Array with unknown body type
2968       assert(this->isa_aryptr(), "only arrays without klass");
2969       _is_ptr_to_narrowoop = UseCompressedOops;
2970     } else if (this->isa_aryptr()) {
2971       _is_ptr_to_narrowoop = (UseCompressedOops && klass()->is_obj_array_klass() &&
2972                              _offset != arrayOopDesc::length_offset_in_bytes());
2973     } else if (klass()->is_instance_klass()) {
2974       ciInstanceKlass* ik = klass()->as_instance_klass();
2975       ciField* field = NULL;
2976       if (this->isa_klassptr()) {
2977         // Perm objects don't use compressed references
2978       } else if (_offset == OffsetBot || _offset == OffsetTop) {
2979         // unsafe access
2980         _is_ptr_to_narrowoop = UseCompressedOops;
2981       } else { // exclude unsafe ops
2982         assert(this->isa_instptr(), "must be an instance ptr.");
2983 
2984         if (klass() == ciEnv::current()->Class_klass() &&
2985             (_offset == java_lang_Class::klass_offset_in_bytes() ||
2986              _offset == java_lang_Class::array_klass_offset_in_bytes())) {
2987           // Special hidden fields from the Class.
2988           assert(this->isa_instptr(), "must be an instance ptr.");
2989           _is_ptr_to_narrowoop = false;
2990         } else if (klass() == ciEnv::current()->Class_klass() &&
2991                    _offset >= InstanceMirrorKlass::offset_of_static_fields()) {

2992           // Static fields
2993           assert(o != NULL, "must be constant");
2994           ciInstanceKlass* k = o->as_instance()->java_lang_Class_klass()->as_instance_klass();
2995           ciField* field = k->get_field_by_offset(_offset, true);
2996           assert(field != NULL, "missing field");
2997           BasicType basic_elem_type = field->layout_type();
2998           _is_ptr_to_narrowoop = UseCompressedOops && (basic_elem_type == T_OBJECT ||
2999                                                        basic_elem_type == T_ARRAY);
3000         } else {
3001           // Instance fields which contains a compressed oop references.
3002           field = ik->get_field_by_offset(_offset, false);
3003           if (field != NULL) {
3004             BasicType basic_elem_type = field->layout_type();
3005             _is_ptr_to_narrowoop = UseCompressedOops && (basic_elem_type == T_OBJECT ||
3006                                                          basic_elem_type == T_ARRAY);
3007           } else if (klass()->equals(ciEnv::current()->Object_klass())) {
3008             // Compile::find_alias_type() cast exactness on all types to verify
3009             // that it does not affect alias type.
3010             _is_ptr_to_narrowoop = UseCompressedOops;
3011           } else {


3027   bool      xk = false;
3028   ciObject* o = NULL;
3029   return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id, speculative, inline_depth))->hashcons();
3030 }
3031 
3032 
3033 //------------------------------cast_to_ptr_type-------------------------------
3034 const Type *TypeOopPtr::cast_to_ptr_type(PTR ptr) const {
3035   assert(_base == OopPtr, "subclass must override cast_to_ptr_type");
3036   if( ptr == _ptr ) return this;
3037   return make(ptr, _offset, _instance_id, _speculative, _inline_depth);
3038 }
3039 
3040 //-----------------------------cast_to_instance_id----------------------------
3041 const TypeOopPtr *TypeOopPtr::cast_to_instance_id(int instance_id) const {
3042   // There are no instances of a general oop.
3043   // Return self unchanged.
3044   return this;
3045 }
3046 




3047 //-----------------------------cast_to_exactness-------------------------------
3048 const Type *TypeOopPtr::cast_to_exactness(bool klass_is_exact) const {
3049   // There is no such thing as an exact general oop.
3050   // Return self unchanged.
3051   return this;
3052 }
3053 
3054 
3055 //------------------------------as_klass_type----------------------------------
3056 // Return the klass type corresponding to this instance or array type.
3057 // It is the type that is loaded from an object of this type.
3058 const TypeKlassPtr* TypeOopPtr::as_klass_type() const {
3059   ciKlass* k = klass();
3060   bool    xk = klass_is_exact();
3061   if (k == NULL)
3062     return TypeKlassPtr::OBJECT;
3063   else
3064     return TypeKlassPtr::make(xk? Constant: NotNull, k, 0);
3065 }
3066 


3529 }
3530 
3531 
3532 //-----------------------------cast_to_exactness-------------------------------
3533 const Type *TypeInstPtr::cast_to_exactness(bool klass_is_exact) const {
3534   if( klass_is_exact == _klass_is_exact ) return this;
3535   if (!UseExactTypes)  return this;
3536   if (!_klass->is_loaded())  return this;
3537   ciInstanceKlass* ik = _klass->as_instance_klass();
3538   if( (ik->is_final() || _const_oop) )  return this;  // cannot clear xk
3539   if( ik->is_interface() )              return this;  // cannot set xk
3540   return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id, _speculative, _inline_depth);
3541 }
3542 
3543 //-----------------------------cast_to_instance_id----------------------------
3544 const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const {
3545   if( instance_id == _instance_id ) return this;
3546   return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id, _speculative, _inline_depth);
3547 }
3548 





3549 //------------------------------xmeet_unloaded---------------------------------
3550 // Compute the MEET of two InstPtrs when at least one is unloaded.
3551 // Assume classes are different since called after check for same name/class-loader
3552 const TypeInstPtr *TypeInstPtr::xmeet_unloaded(const TypeInstPtr *tinst) const {
3553     int off = meet_offset(tinst->offset());
3554     PTR ptr = meet_ptr(tinst->ptr());
3555     int instance_id = meet_instance_id(tinst->instance_id());
3556     const TypePtr* speculative = xmeet_speculative(tinst);
3557     int depth = meet_inline_depth(tinst->inline_depth());
3558 
3559     const TypeInstPtr *loaded    = is_loaded() ? this  : tinst;
3560     const TypeInstPtr *unloaded  = is_loaded() ? tinst : this;
3561     if( loaded->klass()->equals(ciEnv::current()->Object_klass()) ) {
3562       //
3563       // Meet unloaded class with java/lang/Object
3564       //
3565       // Meet
3566       //          |                     Unloaded Class
3567       //  Object  |   TOP    |   AnyNull | Constant |   NotNull |  BOTTOM   |
3568       //  ===================================================================


4055 //------------------------------cast_to_ptr_type-------------------------------
4056 const Type *TypeAryPtr::cast_to_ptr_type(PTR ptr) const {
4057   if( ptr == _ptr ) return this;
4058   return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth);
4059 }
4060 
4061 
4062 //-----------------------------cast_to_exactness-------------------------------
4063 const Type *TypeAryPtr::cast_to_exactness(bool klass_is_exact) const {
4064   if( klass_is_exact == _klass_is_exact ) return this;
4065   if (!UseExactTypes)  return this;
4066   if (_ary->ary_must_be_exact())  return this;  // cannot clear xk
4067   return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id, _speculative, _inline_depth);
4068 }
4069 
4070 //-----------------------------cast_to_instance_id----------------------------
4071 const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const {
4072   if( instance_id == _instance_id ) return this;
4073   return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id, _speculative, _inline_depth);
4074 }






4075 
4076 //-----------------------------narrow_size_type-------------------------------
4077 // Local cache for arrayOopDesc::max_array_length(etype),
4078 // which is kind of slow (and cached elsewhere by other users).
4079 static jint max_array_length_cache[T_CONFLICT+1];
4080 static jint max_array_length(BasicType etype) {
4081   jint& cache = max_array_length_cache[etype];
4082   jint res = cache;
4083   if (res == 0) {
4084     switch (etype) {
4085     case T_NARROWOOP:
4086       etype = T_OBJECT;
4087       break;
4088     case T_NARROWKLASS:
4089     case T_CONFLICT:
4090     case T_ILLEGAL:
4091     case T_VOID:
4092       etype = T_BYTE;           // will produce conservatively high value
4093       break;
4094     default:




  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "ci/ciMethodData.hpp"
  27 #include "ci/ciTypeFlow.hpp"
  28 #include "classfile/symbolTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "compiler/compileLog.hpp"
  31 #include "libadt/dict.hpp"
  32 #include "memory/oopFactory.hpp"
  33 #include "memory/resourceArea.hpp"
  34 #include "oops/instanceKlass.hpp"
  35 #include "oops/instanceMirrorKlass.hpp"
  36 #include "oops/objArrayKlass.hpp"
  37 #include "oops/typeArrayKlass.hpp"
  38 #include "opto/matcher.hpp"
  39 #include "opto/node.hpp"
  40 #include "opto/opcodes.hpp"
  41 #include "opto/type.hpp"
  42 #include "utilities/macros.hpp"
  43 #if INCLUDE_SHENANDOAHGC
  44 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
  45 #endif
  46 
  47 // Portions of code courtesy of Clifford Click
  48 
  49 // Optimization - Graph Style
  50 
  51 // Dictionary of types shared among compilations.
  52 Dict* Type::_shared_type_dict = NULL;
  53 
  54 // Array which maps compiler types to Basic Types
  55 const Type::TypeInfo Type::_type_info[Type::lastype] = {
  56   { Bad,             T_ILLEGAL,    "bad",           false, Node::NotAMachineReg, relocInfo::none          },  // Bad
  57   { Control,         T_ILLEGAL,    "control",       false, 0,                    relocInfo::none          },  // Control
  58   { Bottom,          T_VOID,       "top",           false, 0,                    relocInfo::none          },  // Top
  59   { Bad,             T_INT,        "int:",          false, Op_RegI,              relocInfo::none          },  // Int
  60   { Bad,             T_LONG,       "long:",         false, Op_RegL,              relocInfo::none          },  // Long
  61   { Half,            T_VOID,       "half",          false, 0,                    relocInfo::none          },  // Half
  62   { Bad,             T_NARROWOOP,  "narrowoop:",    false, Op_RegN,              relocInfo::none          },  // NarrowOop
  63   { Bad,             T_NARROWKLASS,"narrowklass:",  false, Op_RegN,              relocInfo::none          },  // NarrowKlass
  64   { Bad,             T_ILLEGAL,    "tuple:",        false, Node::NotAMachineReg, relocInfo::none          },  // Tuple
  65   { Bad,             T_ARRAY,      "array:",        false, Node::NotAMachineReg, relocInfo::none          },  // Array


2950 const TypeOopPtr *TypeOopPtr::BOTTOM;
2951 
2952 //------------------------------TypeOopPtr-------------------------------------
2953 TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset,
2954                        int instance_id, const TypePtr* speculative, int inline_depth)
2955   : TypePtr(t, ptr, offset, speculative, inline_depth),
2956     _const_oop(o), _klass(k),
2957     _klass_is_exact(xk),
2958     _is_ptr_to_narrowoop(false),
2959     _is_ptr_to_narrowklass(false),
2960     _is_ptr_to_boxed_value(false),
2961     _instance_id(instance_id) {
2962   if (Compile::current()->eliminate_boxing() && (t == InstPtr) &&
2963       (offset > 0) && xk && (k != 0) && k->is_instance_klass()) {
2964     _is_ptr_to_boxed_value = k->as_instance_klass()->is_boxed_value_offset(offset);
2965   }
2966 #ifdef _LP64
2967   if (_offset != 0) {
2968     if (_offset == oopDesc::klass_offset_in_bytes()) {
2969       _is_ptr_to_narrowklass = UseCompressedClassPointers;
2970 #if INCLUDE_SHENANDOAHGC
2971     } else if (UseShenandoahGC && _offset == ShenandoahBrooksPointer::byte_offset()) {
2972       // Shenandoah doesn't support compressed forwarding pointers
2973 #endif
2974     } else if (klass() == NULL) {
2975       // Array with unknown body type
2976       assert(this->isa_aryptr(), "only arrays without klass");
2977       _is_ptr_to_narrowoop = UseCompressedOops;
2978     } else if (this->isa_aryptr()) {
2979       _is_ptr_to_narrowoop = (UseCompressedOops && klass()->is_obj_array_klass() &&
2980                              _offset != arrayOopDesc::length_offset_in_bytes());
2981     } else if (klass()->is_instance_klass()) {
2982       ciInstanceKlass* ik = klass()->as_instance_klass();
2983       ciField* field = NULL;
2984       if (this->isa_klassptr()) {
2985         // Perm objects don't use compressed references
2986       } else if (_offset == OffsetBot || _offset == OffsetTop) {
2987         // unsafe access
2988         _is_ptr_to_narrowoop = UseCompressedOops;
2989       } else { // exclude unsafe ops
2990         assert(this->isa_instptr(), "must be an instance ptr.");
2991 
2992         if (klass() == ciEnv::current()->Class_klass() &&
2993             (_offset == java_lang_Class::klass_offset_in_bytes() ||
2994              _offset == java_lang_Class::array_klass_offset_in_bytes())) {
2995           // Special hidden fields from the Class.
2996           assert(this->isa_instptr(), "must be an instance ptr.");
2997           _is_ptr_to_narrowoop = false;
2998         } else if (klass() == ciEnv::current()->Class_klass() &&
2999                    _offset >= InstanceMirrorKlass::offset_of_static_fields() &&
3000                    !UseShenandoahGC) {
3001           // Static fields
3002           assert(o != NULL, "must be constant");
3003           ciInstanceKlass* k = o->as_instance()->java_lang_Class_klass()->as_instance_klass();
3004           ciField* field = k->get_field_by_offset(_offset, true);
3005           assert(field != NULL, "missing field");
3006           BasicType basic_elem_type = field->layout_type();
3007           _is_ptr_to_narrowoop = UseCompressedOops && (basic_elem_type == T_OBJECT ||
3008                                                        basic_elem_type == T_ARRAY);
3009         } else {
3010           // Instance fields which contains a compressed oop references.
3011           field = ik->get_field_by_offset(_offset, false);
3012           if (field != NULL) {
3013             BasicType basic_elem_type = field->layout_type();
3014             _is_ptr_to_narrowoop = UseCompressedOops && (basic_elem_type == T_OBJECT ||
3015                                                          basic_elem_type == T_ARRAY);
3016           } else if (klass()->equals(ciEnv::current()->Object_klass())) {
3017             // Compile::find_alias_type() cast exactness on all types to verify
3018             // that it does not affect alias type.
3019             _is_ptr_to_narrowoop = UseCompressedOops;
3020           } else {


3036   bool      xk = false;
3037   ciObject* o = NULL;
3038   return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id, speculative, inline_depth))->hashcons();
3039 }
3040 
3041 
3042 //------------------------------cast_to_ptr_type-------------------------------
3043 const Type *TypeOopPtr::cast_to_ptr_type(PTR ptr) const {
3044   assert(_base == OopPtr, "subclass must override cast_to_ptr_type");
3045   if( ptr == _ptr ) return this;
3046   return make(ptr, _offset, _instance_id, _speculative, _inline_depth);
3047 }
3048 
3049 //-----------------------------cast_to_instance_id----------------------------
3050 const TypeOopPtr *TypeOopPtr::cast_to_instance_id(int instance_id) const {
3051   // There are no instances of a general oop.
3052   // Return self unchanged.
3053   return this;
3054 }
3055 
3056 const TypeOopPtr *TypeOopPtr::cast_to_nonconst() const {
3057   return this;
3058 }
3059 
3060 //-----------------------------cast_to_exactness-------------------------------
3061 const Type *TypeOopPtr::cast_to_exactness(bool klass_is_exact) const {
3062   // There is no such thing as an exact general oop.
3063   // Return self unchanged.
3064   return this;
3065 }
3066 
3067 
3068 //------------------------------as_klass_type----------------------------------
3069 // Return the klass type corresponding to this instance or array type.
3070 // It is the type that is loaded from an object of this type.
3071 const TypeKlassPtr* TypeOopPtr::as_klass_type() const {
3072   ciKlass* k = klass();
3073   bool    xk = klass_is_exact();
3074   if (k == NULL)
3075     return TypeKlassPtr::OBJECT;
3076   else
3077     return TypeKlassPtr::make(xk? Constant: NotNull, k, 0);
3078 }
3079 


3542 }
3543 
3544 
3545 //-----------------------------cast_to_exactness-------------------------------
3546 const Type *TypeInstPtr::cast_to_exactness(bool klass_is_exact) const {
3547   if( klass_is_exact == _klass_is_exact ) return this;
3548   if (!UseExactTypes)  return this;
3549   if (!_klass->is_loaded())  return this;
3550   ciInstanceKlass* ik = _klass->as_instance_klass();
3551   if( (ik->is_final() || _const_oop) )  return this;  // cannot clear xk
3552   if( ik->is_interface() )              return this;  // cannot set xk
3553   return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id, _speculative, _inline_depth);
3554 }
3555 
3556 //-----------------------------cast_to_instance_id----------------------------
3557 const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const {
3558   if( instance_id == _instance_id ) return this;
3559   return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id, _speculative, _inline_depth);
3560 }
3561 
3562 const TypeOopPtr *TypeInstPtr::cast_to_nonconst() const {
3563   if (const_oop() == NULL) return this;
3564   return make(NotNull, klass(), _klass_is_exact, NULL, _offset, _instance_id, _speculative, _inline_depth);
3565 }
3566 
3567 //------------------------------xmeet_unloaded---------------------------------
3568 // Compute the MEET of two InstPtrs when at least one is unloaded.
3569 // Assume classes are different since called after check for same name/class-loader
3570 const TypeInstPtr *TypeInstPtr::xmeet_unloaded(const TypeInstPtr *tinst) const {
3571     int off = meet_offset(tinst->offset());
3572     PTR ptr = meet_ptr(tinst->ptr());
3573     int instance_id = meet_instance_id(tinst->instance_id());
3574     const TypePtr* speculative = xmeet_speculative(tinst);
3575     int depth = meet_inline_depth(tinst->inline_depth());
3576 
3577     const TypeInstPtr *loaded    = is_loaded() ? this  : tinst;
3578     const TypeInstPtr *unloaded  = is_loaded() ? tinst : this;
3579     if( loaded->klass()->equals(ciEnv::current()->Object_klass()) ) {
3580       //
3581       // Meet unloaded class with java/lang/Object
3582       //
3583       // Meet
3584       //          |                     Unloaded Class
3585       //  Object  |   TOP    |   AnyNull | Constant |   NotNull |  BOTTOM   |
3586       //  ===================================================================


4073 //------------------------------cast_to_ptr_type-------------------------------
4074 const Type *TypeAryPtr::cast_to_ptr_type(PTR ptr) const {
4075   if( ptr == _ptr ) return this;
4076   return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth);
4077 }
4078 
4079 
4080 //-----------------------------cast_to_exactness-------------------------------
4081 const Type *TypeAryPtr::cast_to_exactness(bool klass_is_exact) const {
4082   if( klass_is_exact == _klass_is_exact ) return this;
4083   if (!UseExactTypes)  return this;
4084   if (_ary->ary_must_be_exact())  return this;  // cannot clear xk
4085   return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id, _speculative, _inline_depth);
4086 }
4087 
4088 //-----------------------------cast_to_instance_id----------------------------
4089 const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const {
4090   if( instance_id == _instance_id ) return this;
4091   return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id, _speculative, _inline_depth);
4092 }
4093 
4094 const TypeOopPtr *TypeAryPtr::cast_to_nonconst() const {
4095   if (const_oop() == NULL) return this;
4096   return make(NotNull, NULL, _ary, klass(), _klass_is_exact, _offset, _instance_id, _speculative, _inline_depth);
4097 }
4098 
4099 
4100 //-----------------------------narrow_size_type-------------------------------
4101 // Local cache for arrayOopDesc::max_array_length(etype),
4102 // which is kind of slow (and cached elsewhere by other users).
4103 static jint max_array_length_cache[T_CONFLICT+1];
4104 static jint max_array_length(BasicType etype) {
4105   jint& cache = max_array_length_cache[etype];
4106   jint res = cache;
4107   if (res == 0) {
4108     switch (etype) {
4109     case T_NARROWOOP:
4110       etype = T_OBJECT;
4111       break;
4112     case T_NARROWKLASS:
4113     case T_CONFLICT:
4114     case T_ILLEGAL:
4115     case T_VOID:
4116       etype = T_BYTE;           // will produce conservatively high value
4117       break;
4118     default:


< prev index next >