1 /*
2  * Copyright (C) 2018 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_DEX_REGISTER_LOCATION_H_
18 #define ART_RUNTIME_DEX_REGISTER_LOCATION_H_
19 
20 #include <array>
21 #include <cstdint>
22 
23 #include "base/dchecked_vector.h"
24 #include "base/memory_region.h"
25 
26 namespace art {
27 
28 // Dex register location container used by DexRegisterMap and StackMapStream.
29 class DexRegisterLocation {
30  public:
31   enum class Kind : int32_t {
32     kInvalid = -2,       // only used internally during register map decoding.
33     kNone = -1,          // vreg has not been set.
34     kInStack,            // vreg is on the stack, value holds the stack offset.
35     kConstant,           // vreg is a constant value.
36     kInRegister,         // vreg is in low 32 bits of a core physical register.
37     kInRegisterHigh,     // vreg is in high 32 bits of a core physical register.
38     kInFpuRegister,      // vreg is in low 32 bits of an FPU register.
39     kInFpuRegisterHigh,  // vreg is in high 32 bits of an FPU register.
40   };
41 
DexRegisterLocation(Kind kind,int32_t value)42   DexRegisterLocation(Kind kind, int32_t value) : kind_(kind), value_(value) {}
43 
None()44   static DexRegisterLocation None() { return DexRegisterLocation(Kind::kNone, 0); }
Invalid()45   static DexRegisterLocation Invalid() { return DexRegisterLocation(Kind::kInvalid, 0); }
46 
IsLive()47   bool IsLive() const { return kind_ != Kind::kNone; }
48 
GetKind()49   Kind GetKind() const { return kind_; }
50 
GetValue()51   int32_t GetValue() const { return value_; }
52 
53   bool operator==(DexRegisterLocation other) const {
54     return kind_ == other.kind_ && value_ == other.value_;
55   }
56 
57   bool operator!=(DexRegisterLocation other) const {
58     return !(*this == other);
59   }
60 
GetStackOffsetInBytes()61   int32_t GetStackOffsetInBytes() const {
62     DCHECK(kind_ == Kind::kInStack);
63     return value_;
64   }
65 
GetConstant()66   int32_t GetConstant() const {
67     DCHECK(kind_ == Kind::kConstant);
68     return value_;
69   }
70 
GetMachineRegister()71   int32_t GetMachineRegister() const {
72     DCHECK(kind_ == Kind::kInRegister ||
73            kind_ == Kind::kInRegisterHigh ||
74            kind_ == Kind::kInFpuRegister ||
75            kind_ == Kind::kInFpuRegisterHigh);
76     return value_;
77   }
78 
79  private:
DexRegisterLocation()80   DexRegisterLocation() {}
81 
82   Kind kind_;
83   int32_t value_;
84 
85   friend class DexRegisterMap;  // Allow creation of uninitialized array of locations.
86 };
87 
88 std::ostream& operator<<(std::ostream& stream, DexRegisterLocation::Kind kind);
89 std::ostream& operator<<(std::ostream& stream, const DexRegisterLocation& reg);
90 
91 }  // namespace art
92 
93 #endif  // ART_RUNTIME_DEX_REGISTER_LOCATION_H_
94