mirror of
https://github.com/openharmony/ark_runtime_core.git
synced 2026-07-19 13:17:49 -04:00
14c9021696
Signed-off-by: wanyanglan <wanyanglan1@huawei.com> Change-Id: I2564094cef9c6c41263e37faf9ffbbec14223dc7
97 lines
3.4 KiB
Markdown
97 lines
3.4 KiB
Markdown
# Runtime class
|
|
|
|
Panda runtime uses `panda::Class` to store all necessary language independent information about classes. Virtual table and region for static fields are embedded to the `panda::Class` object so it has variable size. To get fast access to them, the `Class Word` field of the object header points to the instance of this class. `ClassLinker::GetClass` also returns an instance of the `panda::Class`.
|
|
|
|
Pointer to the managed class object (instance of `panda.Class` or `java.lang.Class` in case of Java, for example) can be obtained using `panda::Class::GetManagedObject` method:
|
|
|
|
```cpp
|
|
panda::Class *cls = obj->ClassAddr()->GetManagedObject();
|
|
```
|
|
|
|
Storing common runtime information separately from managed objects allows more flexibility for the layout but causes additional dereferences to get panda::Class from mirror classes and vice versa. However, we can use composition to reduce the number of additional dereferences.
|
|
|
|
```cpp
|
|
namespace panda::coretypes {
|
|
class Class : public ObjectHeader {
|
|
|
|
... // Mirror fields
|
|
|
|
panda::Class klass_;
|
|
};
|
|
} // namespace panda::coretypes
|
|
```
|
|
|
|
The layout of the `coretypes::Class` is as follows:
|
|
|
|
|
|
mirror class (`coretypes::Class`) --------> +------------------+ <-+
|
|
| `Mark Word` | |
|
|
| `Class Word` |-----+
|
|
+------------------+ | |
|
|
| Mirror fields | | |
|
|
panda class (`panda::Class`) ---------> +------------------+ <-|-+
|
|
| ... | |
|
|
| `Managed Object` |---+
|
|
| ... |
|
|
+------------------+
|
|
|
|
Note: The `panda::Class` object must be the last in the mirror class because it has variable size.
|
|
|
|
Such layout allows to get pointer to the `panda::Class` object from the `coretypes::Class` one and vice versa without dereferencies if we know language context and it's constant (some language specific code):
|
|
|
|
```cpp
|
|
auto *managed_class_obj = coretypes::Class::FromRuntimeClass(klass);
|
|
...
|
|
auto *runtime_class = managed_class_obj->GetRuntimeClass();
|
|
```
|
|
|
|
Where `coretypes::Class::FromRuntimeClass` and `coretypes::Class::GetRuntimeClass` are implemented in the following way:
|
|
|
|
|
|
```cpp
|
|
namespace panda::coretypes {
|
|
class Class : public ObjectHeader {
|
|
...
|
|
|
|
panda::Class *GetRuntimeClass() {
|
|
return &klass_;
|
|
}
|
|
|
|
static constexpr size_t GetRuntimeClassOffset() {
|
|
return MEMBER_OFFSET(Class, klass_);
|
|
}
|
|
|
|
static Class *FromRuntimeClass(panda::Class *klass) {
|
|
return reinterpret_cast<Class *>(reinterpret_cast<uintptr_t>(klass) - GetRuntimeClassOffset());
|
|
}
|
|
|
|
...
|
|
};
|
|
} // namespace panda::coretypes
|
|
```
|
|
|
|
In common places where language context can be different we can use `panda::Class::GetManagedObject`. For example:
|
|
|
|
```cpp
|
|
auto *managed_class_obj = klass->GetManagedObject();
|
|
ObjectLock lock(managed_class_obj);
|
|
```
|
|
|
|
Instead of
|
|
|
|
```cpp
|
|
ObjectHeader *managed_class_obj;
|
|
switch (klass->GetSourceLang()) {
|
|
case PANDA_ASSEMBLY: {
|
|
managed_class_obj = coretypes::Class::FromRuntimeClass(klass);
|
|
break;
|
|
}
|
|
case JAVA_8: {
|
|
managed_class_obj = java::JClass::FromRuntimeClass(klass);
|
|
break;
|
|
}
|
|
...
|
|
}
|
|
ObjectLock lock(managed_class_obj);
|
|
```
|