1/*
2 * Copyright (C) 2016 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_IMTABLE_H_
18#define ART_RUNTIME_IMTABLE_H_
19
20#ifndef IMT_SIZE
21#error IMT_SIZE not defined
22#endif
23
24namespace art {
25
26class ArtMethod;
27
28class ImTable {
29 public:
30  // Interface method table size. Increasing this value reduces the chance of two interface methods
31  // colliding in the interface method table but increases the size of classes that implement
32  // (non-marker) interfaces.
33  static constexpr size_t kSize = IMT_SIZE;
34
35  ArtMethod* Get(size_t index, size_t pointer_size) {
36    DCHECK_LT(index, kSize);
37    uint8_t* ptr = reinterpret_cast<uint8_t*>(this) + OffsetOfElement(index, pointer_size);
38    if (pointer_size == 4) {
39      uint32_t value = *reinterpret_cast<uint32_t*>(ptr);
40      return reinterpret_cast<ArtMethod*>(value);
41    } else {
42      uint64_t value = *reinterpret_cast<uint64_t*>(ptr);
43      return reinterpret_cast<ArtMethod*>(value);
44    }
45  }
46
47  void Set(size_t index, ArtMethod* method, size_t pointer_size) {
48    DCHECK_LT(index, kSize);
49    uint8_t* ptr = reinterpret_cast<uint8_t*>(this) + OffsetOfElement(index, pointer_size);
50    if (pointer_size == 4) {
51      uintptr_t value = reinterpret_cast<uintptr_t>(method);
52      DCHECK_EQ(static_cast<uint32_t>(value), value);  // Check that we dont lose any non 0 bits.
53      *reinterpret_cast<uint32_t*>(ptr) = static_cast<uint32_t>(value);
54    } else {
55      *reinterpret_cast<uint64_t*>(ptr) = reinterpret_cast<uint64_t>(method);
56    }
57  }
58
59  static size_t OffsetOfElement(size_t index, size_t pointer_size) {
60    return index * pointer_size;
61  }
62
63  void Populate(ArtMethod** data, size_t pointer_size) {
64    for (size_t i = 0; i < kSize; ++i) {
65      Set(i, data[i], pointer_size);
66    }
67  }
68
69  constexpr static size_t SizeInBytes(size_t pointer_size) {
70    return kSize * pointer_size;
71  }
72};
73
74}  // namespace art
75
76#endif  // ART_RUNTIME_IMTABLE_H_
77
78