Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_RUNTIME_PRIMITIVE_H_
     18 #define ART_RUNTIME_PRIMITIVE_H_
     19 
     20 #include <sys/types.h>
     21 
     22 #include "base/logging.h"
     23 #include "base/macros.h"
     24 
     25 namespace art {
     26 
     27 static constexpr size_t kObjectReferenceSize = 4;
     28 
     29 constexpr size_t ComponentSizeShiftWidth(size_t component_size) {
     30   return component_size == 1u ? 0u :
     31       component_size == 2u ? 1u :
     32           component_size == 4u ? 2u :
     33               component_size == 8u ? 3u : 0u;
     34 }
     35 
     36 class Primitive {
     37  public:
     38   enum Type {
     39     kPrimNot = 0,
     40     kPrimBoolean,
     41     kPrimByte,
     42     kPrimChar,
     43     kPrimShort,
     44     kPrimInt,
     45     kPrimLong,
     46     kPrimFloat,
     47     kPrimDouble,
     48     kPrimVoid,
     49     kPrimLast = kPrimVoid
     50   };
     51 
     52   static Type GetType(char type) {
     53     switch (type) {
     54       case 'B':
     55         return kPrimByte;
     56       case 'C':
     57         return kPrimChar;
     58       case 'D':
     59         return kPrimDouble;
     60       case 'F':
     61         return kPrimFloat;
     62       case 'I':
     63         return kPrimInt;
     64       case 'J':
     65         return kPrimLong;
     66       case 'S':
     67         return kPrimShort;
     68       case 'Z':
     69         return kPrimBoolean;
     70       case 'V':
     71         return kPrimVoid;
     72       default:
     73         return kPrimNot;
     74     }
     75   }
     76 
     77   static size_t ComponentSizeShift(Type type) {
     78     switch (type) {
     79       case kPrimVoid:
     80       case kPrimBoolean:
     81       case kPrimByte:    return 0;
     82       case kPrimChar:
     83       case kPrimShort:   return 1;
     84       case kPrimInt:
     85       case kPrimFloat:   return 2;
     86       case kPrimLong:
     87       case kPrimDouble:  return 3;
     88       case kPrimNot:     return ComponentSizeShiftWidth(kObjectReferenceSize);
     89       default:
     90         LOG(FATAL) << "Invalid type " << static_cast<int>(type);
     91         return 0;
     92     }
     93   }
     94 
     95   static size_t ComponentSize(Type type) {
     96     switch (type) {
     97       case kPrimVoid:    return 0;
     98       case kPrimBoolean:
     99       case kPrimByte:    return 1;
    100       case kPrimChar:
    101       case kPrimShort:   return 2;
    102       case kPrimInt:
    103       case kPrimFloat:   return 4;
    104       case kPrimLong:
    105       case kPrimDouble:  return 8;
    106       case kPrimNot:     return kObjectReferenceSize;
    107       default:
    108         LOG(FATAL) << "Invalid type " << static_cast<int>(type);
    109         return 0;
    110     }
    111   }
    112 
    113   static const char* Descriptor(Type type) {
    114     switch (type) {
    115       case kPrimBoolean:
    116         return "Z";
    117       case kPrimByte:
    118         return "B";
    119       case kPrimChar:
    120         return "C";
    121       case kPrimShort:
    122         return "S";
    123       case kPrimInt:
    124         return "I";
    125       case kPrimFloat:
    126         return "F";
    127       case kPrimLong:
    128         return "J";
    129       case kPrimDouble:
    130         return "D";
    131       case kPrimVoid:
    132         return "V";
    133       default:
    134         LOG(FATAL) << "Primitive char conversion on invalid type " << static_cast<int>(type);
    135         return nullptr;
    136     }
    137   }
    138 
    139   static const char* PrettyDescriptor(Type type);
    140 
    141   static bool IsFloatingPointType(Type type) {
    142     return type == kPrimFloat || type == kPrimDouble;
    143   }
    144 
    145   static bool IsIntegralType(Type type) {
    146     // The Java language does not allow treating boolean as an integral type but
    147     // our bit representation makes it safe.
    148     switch (type) {
    149       case kPrimBoolean:
    150       case kPrimByte:
    151       case kPrimChar:
    152       case kPrimShort:
    153       case kPrimInt:
    154       case kPrimLong:
    155         return true;
    156       default:
    157         return false;
    158     }
    159   }
    160 
    161   static bool IsIntOrLongType(Type type) {
    162     return type == kPrimInt || type == kPrimLong;
    163   }
    164 
    165   static bool Is64BitType(Type type) {
    166     return type == kPrimLong || type == kPrimDouble;
    167   }
    168 
    169   // Return the general kind of `type`, fusing integer-like types as kPrimInt.
    170   static Type PrimitiveKind(Type type) {
    171     switch (type) {
    172       case kPrimBoolean:
    173       case kPrimByte:
    174       case kPrimShort:
    175       case kPrimChar:
    176       case kPrimInt:
    177         return kPrimInt;
    178       default:
    179         return type;
    180     }
    181   }
    182 
    183   static int64_t MinValueOfIntegralType(Type type) {
    184     switch (type) {
    185       case kPrimBoolean:
    186         return std::numeric_limits<bool>::min();
    187       case kPrimByte:
    188         return std::numeric_limits<int8_t>::min();
    189       case kPrimChar:
    190         return std::numeric_limits<uint16_t>::min();
    191       case kPrimShort:
    192         return std::numeric_limits<int16_t>::min();
    193       case kPrimInt:
    194         return std::numeric_limits<int32_t>::min();
    195       case kPrimLong:
    196         return std::numeric_limits<int64_t>::min();
    197       default:
    198         LOG(FATAL) << "non integral type";
    199     }
    200     return 0;
    201   }
    202 
    203   static int64_t MaxValueOfIntegralType(Type type) {
    204     switch (type) {
    205       case kPrimBoolean:
    206         return std::numeric_limits<bool>::max();
    207       case kPrimByte:
    208         return std::numeric_limits<int8_t>::max();
    209       case kPrimChar:
    210         return std::numeric_limits<uint16_t>::max();
    211       case kPrimShort:
    212         return std::numeric_limits<int16_t>::max();
    213       case kPrimInt:
    214         return std::numeric_limits<int32_t>::max();
    215       case kPrimLong:
    216         return std::numeric_limits<int64_t>::max();
    217       default:
    218         LOG(FATAL) << "non integral type";
    219     }
    220     return 0;
    221   }
    222 
    223  private:
    224   DISALLOW_IMPLICIT_CONSTRUCTORS(Primitive);
    225 };
    226 
    227 std::ostream& operator<<(std::ostream& os, const Primitive::Type& state);
    228 
    229 }  // namespace art
    230 
    231 #endif  // ART_RUNTIME_PRIMITIVE_H_
    232