- use the new ObjectType list with fixed indices

svn path=/trunk/; revision=28892
This commit is contained in:
Timo Kreuzer 2007-09-06 02:54:17 +00:00
parent 2aaf1f0e51
commit ad90579751

View file

@ -48,13 +48,6 @@ KeRosDumpStackFrames(
/* apparently the first 10 entries are never used in windows as they are empty */ /* apparently the first 10 entries are never used in windows as they are empty */
#define RESERVE_ENTRIES_COUNT 10 #define RESERVE_ENTRIES_COUNT 10
typedef struct
{
ULONG Type;
ULONG Size;
GDICLEANUPPROC CleanupProc;
} GDI_OBJ_INFO, *PGDI_OBJ_INFO;
/* /*
* Dummy GDI Cleanup Callback * Dummy GDI Cleanup Callback
*/ */
@ -64,31 +57,6 @@ GDI_CleanupDummy(PVOID ObjectBody)
return TRUE; return TRUE;
} }
/* Testing shows that regions are the most used GDIObj type,
so put that one first for performance */
static const
GDI_OBJ_INFO ObjInfo[] =
{
/* Type */ /* Size */ /* CleanupProc */
{GDI_OBJECT_TYPE_REGION, sizeof(ROSRGNDATA), RGNDATA_Cleanup},
{GDI_OBJECT_TYPE_BITMAP, sizeof(BITMAPOBJ), BITMAP_Cleanup},
{GDI_OBJECT_TYPE_DC, sizeof(DC), DC_Cleanup},
{GDI_OBJECT_TYPE_PALETTE, sizeof(PALGDI), PALETTE_Cleanup},
{GDI_OBJECT_TYPE_BRUSH, sizeof(GDIBRUSHOBJ), BRUSH_Cleanup},
{GDI_OBJECT_TYPE_PEN, sizeof(GDIBRUSHOBJ), BRUSH_Cleanup},
{GDI_OBJECT_TYPE_FONT, sizeof(TEXTOBJ), GDI_CleanupDummy},
{GDI_OBJECT_TYPE_DIRECTDRAW, sizeof(DD_DIRECTDRAW), DD_Cleanup},
{GDI_OBJECT_TYPE_DD_SURFACE, sizeof(DD_SURFACE), DDSURF_Cleanup},
{GDI_OBJECT_TYPE_EXTPEN, sizeof(GDIBRUSHOBJ), BRUSH_Cleanup},
/* FIXME do not use normal DC struct for this */
{GDI_OBJECT_TYPE_METADC, sizeof(DC), GDI_CleanupDummy},
{GDI_OBJECT_TYPE_METAFILE, sizeof(DC), GDI_CleanupDummy},
{GDI_OBJECT_TYPE_ENHMETAFILE, 0, GDI_CleanupDummy},
{GDI_OBJECT_TYPE_EMF, 0, GDI_CleanupDummy}
};
#define OBJTYPE_COUNT (sizeof(ObjInfo) / sizeof(ObjInfo[0]))
typedef struct typedef struct
{ {
BOOL bUseLookaside; BOOL bUseLookaside;
@ -200,7 +168,7 @@ GDIOBJ_iAllocHandleTable(OUT PSECTION_OBJECT *SectionObject)
} }
HandleTable->LookasideLists = ExAllocatePoolWithTag(NonPagedPool, HandleTable->LookasideLists = ExAllocatePoolWithTag(NonPagedPool,
OBJTYPE_COUNT * sizeof(PAGED_LOOKASIDE_LIST), BASE_OBJTYPE_COUNT * sizeof(PAGED_LOOKASIDE_LIST),
TAG_GDIHNDTBLE); TAG_GDIHNDTBLE);
if(HandleTable->LookasideLists == NULL) if(HandleTable->LookasideLists == NULL)
{ {
@ -210,10 +178,13 @@ GDIOBJ_iAllocHandleTable(OUT PSECTION_OBJECT *SectionObject)
return NULL; return NULL;
} }
for(ObjType = 0; ObjType < OBJTYPE_COUNT; ObjType++) for(ObjType = 0; ObjType < BASE_OBJTYPE_COUNT; ObjType++)
{
if (ObjTypeInfo[ObjType].bUseLookaside)
{ {
ExInitializePagedLookasideList(HandleTable->LookasideLists + ObjType, NULL, NULL, 0, ExInitializePagedLookasideList(HandleTable->LookasideLists + ObjType, NULL, NULL, 0,
ObjInfo[ObjType].Size + sizeof(GDIOBJHDR), TAG_GDIOBJ, 0); ObjTypeInfo[ObjType].ulBodySize + sizeof(GDIOBJHDR), ObjTypeInfo[ObjType].Tag, 0);
}
} }
ShortDelay.QuadPart = -5000LL; /* FIXME - 0.5 ms? */ ShortDelay.QuadPart = -5000LL; /* FIXME - 0.5 ms? */
@ -223,55 +194,21 @@ GDIOBJ_iAllocHandleTable(OUT PSECTION_OBJECT *SectionObject)
static __inline PPAGED_LOOKASIDE_LIST static __inline PPAGED_LOOKASIDE_LIST
FindLookasideList(PGDI_HANDLE_TABLE HandleTable, FindLookasideList(PGDI_HANDLE_TABLE HandleTable,
DWORD ObjectType) ULONG TypeIndex)
{ {
int Index; return HandleTable->LookasideLists + TypeIndex;
for (Index = 0; Index < OBJTYPE_COUNT; Index++)
{
if (ObjInfo[Index].Type == ObjectType)
{
return HandleTable->LookasideLists + Index;
}
}
DPRINT1("Can't find lookaside list for object type 0x%08x\n", ObjectType);
return NULL;
} }
static __inline BOOL static __inline BOOL
RunCleanupCallback(PGDIOBJ pObj, DWORD ObjectType) RunCleanupCallback(PGDIOBJ pObj, ULONG TypeIndex)
{ {
int Index; return ((GDICLEANUPPROC)ObjTypeInfo[TypeIndex].CleanupProc)(pObj);
for (Index = 0; Index < OBJTYPE_COUNT; Index++)
{
if (ObjInfo[Index].Type == ObjectType)
{
return ((GDICLEANUPPROC)ObjInfo[Index].CleanupProc)(pObj);
}
}
DPRINT1("Can't find cleanup callback for object type 0x%08x\n", ObjectType);
return TRUE;
} }
static __inline ULONG static __inline ULONG
GetObjectSize(DWORD ObjectType) GetObjectSize(ULONG TypeIndex)
{ {
int Index; return ObjTypeInfo[TypeIndex].ulBodySize;
for (Index = 0; Index < OBJTYPE_COUNT; Index++)
{
if (ObjInfo[Index].Type == ObjectType)
{
return ObjInfo[Index].Size;
}
}
DPRINT1("Can't find size for object type 0x%08x\n", ObjectType);
return 0;
} }
#ifdef GDI_DEBUG #ifdef GDI_DEBUG
@ -411,9 +348,10 @@ GDIOBJ_AllocObj(PGDI_HANDLE_TABLE HandleTable, ULONG ObjectType)
#endif /* GDI_DEBUG */ #endif /* GDI_DEBUG */
{ {
PW32PROCESS W32Process; PW32PROCESS W32Process;
PGDIOBJHDR newObject; PGDIOBJHDR newObject = NULL;
PPAGED_LOOKASIDE_LIST LookasideList; PPAGED_LOOKASIDE_LIST LookasideList = NULL;
HANDLE CurrentProcessId, LockedProcessId; HANDLE CurrentProcessId, LockedProcessId;
ULONG TypeIndex;
#ifdef GDI_DEBUG #ifdef GDI_DEBUG
ULONG Attempts = 0; ULONG Attempts = 0;
#endif #endif
@ -426,10 +364,21 @@ GDIOBJ_AllocObj(PGDI_HANDLE_TABLE HandleTable, ULONG ObjectType)
ASSERT(ObjectType != GDI_OBJECT_TYPE_DONTCARE); ASSERT(ObjectType != GDI_OBJECT_TYPE_DONTCARE);
LookasideList = FindLookasideList(HandleTable, ObjectType); TypeIndex = GDI_OBJECT_GET_TYPE_INDEX(ObjectType);
if (ObjTypeInfo[TypeIndex].bUseLookaside)
{
LookasideList = FindLookasideList(HandleTable, TypeIndex);
if(LookasideList != NULL) if(LookasideList != NULL)
{ {
newObject = ExAllocateFromPagedLookasideList(LookasideList); newObject = ExAllocateFromPagedLookasideList(LookasideList);
}
}
else
{
newObject = ExAllocatePoolWithTag(PagedPool,
ObjTypeInfo[TypeIndex].ulBodySize + sizeof(GDIOBJHDR),
ObjTypeInfo[TypeIndex].Tag);
}
if(newObject != NULL) if(newObject != NULL)
{ {
PSLIST_ENTRY FreeEntry; PSLIST_ENTRY FreeEntry;
@ -452,7 +401,7 @@ GDIOBJ_AllocObj(PGDI_HANDLE_TABLE HandleTable, ULONG ObjectType)
ObjectBody = GDIHdrToBdy(newObject); ObjectBody = GDIHdrToBdy(newObject);
RtlZeroMemory(ObjectBody, GetObjectSize(ObjectType)); RtlZeroMemory(ObjectBody, GetObjectSize(TypeIndex));
/* FIXME: On Windows the higher 16 bit of the type field don't always match /* FIXME: On Windows the higher 16 bit of the type field don't always match
the type from the handle, it is probably a storage type the type from the handle, it is probably a storage type
@ -521,7 +470,14 @@ LockHandle:
} }
} }
if (ObjTypeInfo[TypeIndex].bUseLookaside)
{
ExFreeToPagedLookasideList(LookasideList, newObject); ExFreeToPagedLookasideList(LookasideList, newObject);
}
else
{
ExFreePool(newObject);
}
DPRINT1("Failed to insert gdi object into the handle table, no handles left!\n"); DPRINT1("Failed to insert gdi object into the handle table, no handles left!\n");
#ifdef GDI_DEBUG #ifdef GDI_DEBUG
IntDumpHandleTable(HandleTable); IntDumpHandleTable(HandleTable);
@ -531,11 +487,6 @@ LockHandle:
{ {
DPRINT1("Not enough memory to allocate gdi object!\n"); DPRINT1("Not enough memory to allocate gdi object!\n");
} }
}
else
{
DPRINT1("Failed to find lookaside list for object type 0x%x\n", ObjectType);
}
return NULL; return NULL;
} }
@ -559,7 +510,7 @@ GDIOBJ_FreeObj(PGDI_HANDLE_TABLE HandleTable, HGDIOBJ hObj, DWORD ExpectedType)
PGDI_TABLE_ENTRY Entry; PGDI_TABLE_ENTRY Entry;
PPAGED_LOOKASIDE_LIST LookasideList; PPAGED_LOOKASIDE_LIST LookasideList;
HANDLE ProcessId, LockedProcessId, PrevProcId; HANDLE ProcessId, LockedProcessId, PrevProcId;
ULONG HandleType, HandleUpper; ULONG HandleType, HandleUpper, TypeIndex;
BOOL Silent; BOOL Silent;
#ifdef GDI_DEBUG #ifdef GDI_DEBUG
ULONG Attempts = 0; ULONG Attempts = 0;
@ -632,14 +583,22 @@ LockHandle:
} }
/* call the cleanup routine. */ /* call the cleanup routine. */
Ret = RunCleanupCallback(GDIHdrToBdy(GdiHdr), HandleType); TypeIndex = GDI_OBJECT_GET_TYPE_INDEX(HandleType);
Ret = RunCleanupCallback(GDIHdrToBdy(GdiHdr), TypeIndex);
/* Now it's time to free the memory */ /* Now it's time to free the memory */
LookasideList = FindLookasideList(HandleTable, HandleType); if (ObjTypeInfo[TypeIndex].bUseLookaside)
{
LookasideList = FindLookasideList(HandleTable, TypeIndex);
if(LookasideList != NULL) if(LookasideList != NULL)
{ {
ExFreeToPagedLookasideList(LookasideList, GdiHdr); ExFreeToPagedLookasideList(LookasideList, GdiHdr);
} }
}
else
{
ExFreePool(GdiHdr);
}
return Ret; return Ret;
} }