Stash handles rather than native pointers in Ke* objects.

This commit is contained in:
Dr. Chat 2015-12-01 17:15:50 -06:00 committed by Ben Vanik
parent 4301641bdf
commit 52ec24ea6a
2 changed files with 14 additions and 15 deletions

View File

@ -334,7 +334,7 @@ void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) {
// Stash pointer in struct.
// FIXME: This assumes the object has a dispatch header (some don't!)
StashNative(header, this);
StashHandle(header, handle());
guest_object_ptr_ = native_ptr;
}
@ -348,10 +348,10 @@ object_ref<XObject> XObject::GetNativeObject(KernelState* kernel_state,
// we never see it and just randomly start getting passed events/timers/etc.
// Luckily it seems like all other calls (Set/Reset/Wait/etc) are used and
// we don't have to worry about PPC code poking the struct. Because of that,
// we init on first use, store our pointer in the struct, and dereference it
// we init on first use, store our handle in the struct, and dereference it
// each time.
// We identify this by checking the low bit of wait_list_blink - if it's 1,
// we have already put our pointer in there.
// We identify this by setting wait_list_flink to a magic value. When set,
// wait_list_blink will hold a handle to our object.
auto global_lock = xe::global_critical_region::AcquireDirect();
@ -361,13 +361,14 @@ object_ref<XObject> XObject::GetNativeObject(KernelState* kernel_state,
as_type = header->type;
}
if (header->wait_list_blink & 0x1) {
if (header->wait_list_flink == 'XEN\0') {
// Already initialized.
uint64_t object_ptr = ((uint64_t)header->wait_list_flink << 32) |
((header->wait_list_blink) & ~0x1);
XObject* object = reinterpret_cast<XObject*>(object_ptr);
// TODO: assert if the type of the object != as_type
uint32_t handle = header->wait_list_blink;
auto object = kernel_state->object_table()->LookupObject<XObject>(handle);
// TODO(benvanik): assert nothing has been changed in the struct.
return retain_object<XObject>(object);
return object;
} else {
// First use, create new.
// http://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html
@ -412,7 +413,7 @@ object_ref<XObject> XObject::GetNativeObject(KernelState* kernel_state,
// Stash pointer in struct.
// FIXME: This assumes the object contains a dispatch header (some don't!)
StashNative(header, object);
StashHandle(header, object->handle());
// NOTE: we are double-retaining, as the object is implicitly created and
// can never be released.

View File

@ -202,11 +202,9 @@ class XObject {
}
// Stash native pointer into X_DISPATCH_HEADER
static void StashNative(X_DISPATCH_HEADER* header, void* native_ptr) {
uint64_t object_ptr = reinterpret_cast<uint64_t>(native_ptr);
object_ptr |= 0x1;
header->wait_list_flink = (uint32_t)(object_ptr >> 32);
header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
static void StashHandle(X_DISPATCH_HEADER* header, uint32_t handle) {
header->wait_list_flink = 'XEN\0';
header->wait_list_blink = handle;
}
static uint32_t TimeoutTicksToMs(int64_t timeout_ticks);