321 lines
11 KiB
C++
321 lines
11 KiB
C++
|
/*===================================================================
|
||
|
Microsoft Denali
|
||
|
|
||
|
Microsoft Confidential.
|
||
|
Copyright 1996 Microsoft Corporation. All Rights Reserved.
|
||
|
|
||
|
Component: Per-Class Memory Management
|
||
|
|
||
|
File: Memcls.cpp
|
||
|
|
||
|
Owner: dmitryr
|
||
|
|
||
|
This file contains the code to access ATQ memory cache on per
|
||
|
class basis
|
||
|
===================================================================*/
|
||
|
|
||
|
#include "denpre.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include "asperror.h"
|
||
|
#include "clcert.h"
|
||
|
#include "context.h"
|
||
|
#include "cookies.h"
|
||
|
#include "request.h"
|
||
|
#include "response.h"
|
||
|
#include "server.h"
|
||
|
#include "strlist.h"
|
||
|
#include "tlbcache.h"
|
||
|
#include "memcls.h"
|
||
|
|
||
|
// Don't #include "memchk.h" in this file
|
||
|
|
||
|
/*===================================================================
|
||
|
DEBUG only
|
||
|
|
||
|
gs_cTotalObjectsLeaked counts memory leaks
|
||
|
|
||
|
DebugCheckLeaks() outputs the ATQ cache memory
|
||
|
leaks into denmem.log
|
||
|
|
||
|
DEBUG_ACACHE_UNINIT() and DEBUG_ACACHE_FSA_UNINIT() call
|
||
|
DebugCheckLeaks() in DEBUG mode only
|
||
|
===================================================================*/
|
||
|
|
||
|
#ifdef DBG
|
||
|
|
||
|
static DWORD gs_cTotalObjectsLeaked = 0;
|
||
|
|
||
|
#define SZ_MEMCLS_LOG_FILE "C:\\TEMP\\MEMCLS.LOG"
|
||
|
|
||
|
static void DebugCheckLeaks(ALLOC_CACHE_HANDLER *pach, const char *szClass)
|
||
|
{
|
||
|
ALLOC_CACHE_STATISTICS acStats;
|
||
|
pach->QueryStats(&acStats);
|
||
|
DWORD cLeaked = acStats.nTotal - acStats.nFreeEntries;
|
||
|
|
||
|
if (cLeaked > 0)
|
||
|
{
|
||
|
gs_cTotalObjectsLeaked += cLeaked;
|
||
|
|
||
|
DebugFilePrintf
|
||
|
(
|
||
|
SZ_MEMCLS_LOG_FILE,
|
||
|
"MEMCLS: ATQ allocation cache leak: %d of %s objects.\n",
|
||
|
cLeaked,
|
||
|
szClass
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#define DEBUG_ACACHE_UNINIT(C) { DebugCheckLeaks(C::sm_pach, #C); \
|
||
|
ACACHE_UNINIT(C) }
|
||
|
#define DEBUG_ACACHE_FSA_UNINIT(C) { DebugCheckLeaks(g_pach##C, #C); \
|
||
|
ACACHE_FSA_UNINIT(C) }
|
||
|
#else
|
||
|
|
||
|
#define DEBUG_ACACHE_UNINIT(C) ACACHE_UNINIT(C)
|
||
|
#define DEBUG_ACACHE_FSA_UNINIT(C) ACACHE_FSA_UNINIT(C)
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/*===================================================================
|
||
|
For each class with ACACHE_INCLASS_DEFINITIONS() inside add
|
||
|
here ACACHE_CODE macro.
|
||
|
===================================================================*/
|
||
|
|
||
|
ACACHE_CODE(C449Cookie)
|
||
|
ACACHE_CODE(C449File)
|
||
|
ACACHE_CODE(CASEElem)
|
||
|
ACACHE_CODE(CActiveScriptEngine)
|
||
|
ACACHE_CODE(CAppln)
|
||
|
ACACHE_CODE(CApplnVariants)
|
||
|
ACACHE_CODE(CASPError)
|
||
|
ACACHE_CODE(CClCert)
|
||
|
ACACHE_CODE(CComponentCollection)
|
||
|
ACACHE_CODE(CComponentObject)
|
||
|
ACACHE_CODE(CCookie)
|
||
|
ACACHE_CODE(CDebugResponseBuffer)
|
||
|
ACACHE_CODE(CEngineDispElem)
|
||
|
ACACHE_CODE(CFileApplnList)
|
||
|
ACACHE_CODE(CHitObj)
|
||
|
ACACHE_CODE(CHTTPHeader)
|
||
|
ACACHE_CODE(CIsapiReqInfo)
|
||
|
ACACHE_CODE(CPageComponentManager)
|
||
|
ACACHE_CODE(CPageObject)
|
||
|
ACACHE_CODE(CRequest)
|
||
|
ACACHE_CODE(CRequestData)
|
||
|
ACACHE_CODE(CRequestHit)
|
||
|
ACACHE_CODE(CResponse)
|
||
|
ACACHE_CODE(CResponseBuffer)
|
||
|
ACACHE_CODE(CResponseData)
|
||
|
ACACHE_CODE(CScriptingNamespace)
|
||
|
ACACHE_CODE(CScriptingContext)
|
||
|
ACACHE_CODE(CServer)
|
||
|
ACACHE_CODE(CServerData)
|
||
|
ACACHE_CODE(CSession)
|
||
|
ACACHE_CODE(CSessionVariants)
|
||
|
ACACHE_CODE(CStringList)
|
||
|
ACACHE_CODE(CStringListElem)
|
||
|
ACACHE_CODE(CTemplate)
|
||
|
//ACACHE_CODE(CTemplate::CBuffer)
|
||
|
ACACHE_CODE(CTemplate::CFileMap)
|
||
|
ACACHE_CODE(CTypelibCacheEntry)
|
||
|
ACACHE_CODE(CVariantsIterator)
|
||
|
ACACHE_CODE(CViperActivity)
|
||
|
ACACHE_CODE(CViperAsyncRequest)
|
||
|
|
||
|
/*===================================================================
|
||
|
For each fixed size allocator add here ACACHE_FSA_DEFINITION macro.
|
||
|
===================================================================*/
|
||
|
|
||
|
ACACHE_FSA_DEFINITION(MemBlock128)
|
||
|
ACACHE_FSA_DEFINITION(MemBlock256)
|
||
|
ACACHE_FSA_DEFINITION(ResponseBuffer)
|
||
|
|
||
|
/*===================================================================
|
||
|
Defines for cache threshold of each kind
|
||
|
===================================================================*/
|
||
|
#define HARDCODED_PER_APPLN_CACHE_MAX 128
|
||
|
#define HARDCODED_PER_REQUEST_CACHE_MAX 1024
|
||
|
#define HARDCODED_PER_QUEUEITEM_CACHE_MAX 8192
|
||
|
#define HARDCODED_PER_SESSION_CACHE_MAX 8192
|
||
|
#define HARDCODED_PER_SCRPTENG_CACHE_MAX 256
|
||
|
#define HARDCODED_PER_TEMPLATE_CACHE_MAX 2048
|
||
|
#define HARDCODED_PER_RESPONSE_BUFFER_MAX 64
|
||
|
#define HARDCODED_PER_SIZE_BUFFER_MAX 4096
|
||
|
|
||
|
// do scaling per registry setting
|
||
|
DWORD dwMemClsScaleFactor;
|
||
|
|
||
|
#define PER_APPLN_CACHE_MAX ((HARDCODED_PER_APPLN_CACHE_MAX * dwMemClsScaleFactor) / 100)
|
||
|
#define PER_REQUEST_CACHE_MAX ((HARDCODED_PER_REQUEST_CACHE_MAX * dwMemClsScaleFactor) / 100)
|
||
|
#define PER_QUEUEITEM_CACHE_MAX ((HARDCODED_PER_QUEUEITEM_CACHE_MAX * dwMemClsScaleFactor) / 100)
|
||
|
#define PER_SESSION_CACHE_MAX ((HARDCODED_PER_SESSION_CACHE_MAX * dwMemClsScaleFactor) / 100)
|
||
|
#define PER_SCRPTENG_CACHE_MAX ((HARDCODED_PER_SCRPTENG_CACHE_MAX * dwMemClsScaleFactor) / 100)
|
||
|
#define PER_TEMPLATE_CACHE_MAX ((HARDCODED_PER_TEMPLATE_CACHE_MAX * dwMemClsScaleFactor) / 100)
|
||
|
#define PER_RESPONSE_BUFFER_MAX ((HARDCODED_PER_RESPONSE_BUFFER_MAX * dwMemClsScaleFactor) / 100)
|
||
|
#define PER_SIZE_BUFFER_MAX ((HARDCODED_PER_SIZE_BUFFER_MAX * dwMemClsScaleFactor) / 100)
|
||
|
|
||
|
/*===================================================================
|
||
|
InitMemCls
|
||
|
|
||
|
To be called from DllInit(). Creates per-class ATQ memory allocators.
|
||
|
|
||
|
For each class with ACACHE_INCLASS_DEFINITIONS() inside add
|
||
|
here ACACHE_INIT macro.
|
||
|
|
||
|
For each ACACHE_FSA_DEFINITION() add here ACACHE_FSA_INIT macro.
|
||
|
|
||
|
Parameters
|
||
|
|
||
|
Returns:
|
||
|
HRESULT
|
||
|
===================================================================*/
|
||
|
HRESULT InitMemCls()
|
||
|
{
|
||
|
// Set the scaling to normal
|
||
|
dwMemClsScaleFactor = 100;
|
||
|
|
||
|
// Init the allocators
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
ACACHE_INIT(C449Cookie, PER_TEMPLATE_CACHE_MAX/4, hr)
|
||
|
ACACHE_INIT(C449File, PER_TEMPLATE_CACHE_MAX/4, hr)
|
||
|
ACACHE_INIT(CASEElem, PER_SCRPTENG_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CActiveScriptEngine, PER_SCRPTENG_CACHE_MAX, hr)
|
||
|
ACACHE_INIT_EX(CAppln, PER_APPLN_CACHE_MAX, FALSE, hr)
|
||
|
ACACHE_INIT(CApplnVariants, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CASPError, PER_RESPONSE_BUFFER_MAX,hr)
|
||
|
ACACHE_INIT(CClCert, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CComponentCollection, PER_SESSION_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CComponentObject, 2*PER_SESSION_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CCookie, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CDebugResponseBuffer, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CEngineDispElem, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CFileApplnList, 2*PER_APPLN_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CHitObj, PER_QUEUEITEM_CACHE_MAX,hr)
|
||
|
ACACHE_INIT(CHTTPHeader, 2*PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CIsapiReqInfo, PER_QUEUEITEM_CACHE_MAX,hr)
|
||
|
ACACHE_INIT(CPageComponentManager, PER_QUEUEITEM_CACHE_MAX,hr)
|
||
|
ACACHE_INIT(CPageObject, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CRequest, PER_SESSION_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CRequestData, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CRequestHit, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CResponse, PER_SESSION_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CResponseBuffer, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CResponseData, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CScriptingContext, PER_SESSION_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CScriptingNamespace, PER_SESSION_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CServer, PER_SESSION_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CServerData, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT_EX(CSession, PER_SESSION_CACHE_MAX, FALSE, hr)
|
||
|
ACACHE_INIT(CSessionVariants, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CStringList, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CStringListElem, 2*PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CTemplate, PER_TEMPLATE_CACHE_MAX, hr)
|
||
|
// ACACHE_INIT(CTemplate::CBuffer, PER_TEMPLATE_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CTemplate::CFileMap, PER_TEMPLATE_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CTypelibCacheEntry, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CVariantsIterator, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CViperActivity, PER_REQUEST_CACHE_MAX, hr)
|
||
|
ACACHE_INIT(CViperAsyncRequest, PER_QUEUEITEM_CACHE_MAX,hr)
|
||
|
|
||
|
ACACHE_FSA_INIT(MemBlock128, 128, PER_SIZE_BUFFER_MAX, hr)
|
||
|
ACACHE_FSA_INIT(MemBlock256, 256, PER_SIZE_BUFFER_MAX, hr)
|
||
|
ACACHE_FSA_INIT(ResponseBuffer, RESPONSE_BUFFER_SIZE, PER_RESPONSE_BUFFER_MAX, hr)
|
||
|
|
||
|
#ifdef DBG
|
||
|
unlink(SZ_MEMCLS_LOG_FILE);
|
||
|
|
||
|
DebugFilePrintf
|
||
|
(
|
||
|
SZ_MEMCLS_LOG_FILE,
|
||
|
"MEMCLS: ATQ allocation cache inited with HRESULT=%08x.\n",
|
||
|
hr
|
||
|
);
|
||
|
#endif
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
/*===================================================================
|
||
|
UnInitMemCls
|
||
|
|
||
|
To be called from DllInit(). Deletes per-class ATQ memory allocators.
|
||
|
|
||
|
For each class with ACACHE_INCLASS_DEFINITIONS() inside add
|
||
|
here ACACHE_UNINIT macro.
|
||
|
|
||
|
For each ACACHE_FSA_DEFINITION() add here ACACHE_FSA_UNINIT macro.
|
||
|
|
||
|
Parameters
|
||
|
|
||
|
Returns:
|
||
|
HRESULT
|
||
|
===================================================================*/
|
||
|
HRESULT UnInitMemCls()
|
||
|
{
|
||
|
#ifdef DBG
|
||
|
gs_cTotalObjectsLeaked = 0;
|
||
|
#endif
|
||
|
|
||
|
DEBUG_ACACHE_UNINIT(C449Cookie)
|
||
|
DEBUG_ACACHE_UNINIT(C449File)
|
||
|
DEBUG_ACACHE_UNINIT(CASEElem)
|
||
|
DEBUG_ACACHE_UNINIT(CActiveScriptEngine)
|
||
|
DEBUG_ACACHE_UNINIT(CAppln)
|
||
|
DEBUG_ACACHE_UNINIT(CApplnVariants)
|
||
|
DEBUG_ACACHE_UNINIT(CASPError)
|
||
|
DEBUG_ACACHE_UNINIT(CClCert)
|
||
|
DEBUG_ACACHE_UNINIT(CComponentCollection)
|
||
|
DEBUG_ACACHE_UNINIT(CComponentObject)
|
||
|
DEBUG_ACACHE_UNINIT(CCookie)
|
||
|
DEBUG_ACACHE_UNINIT(CDebugResponseBuffer)
|
||
|
DEBUG_ACACHE_UNINIT(CEngineDispElem)
|
||
|
DEBUG_ACACHE_UNINIT(CFileApplnList)
|
||
|
DEBUG_ACACHE_UNINIT(CHitObj)
|
||
|
DEBUG_ACACHE_UNINIT(CHTTPHeader)
|
||
|
DEBUG_ACACHE_UNINIT(CIsapiReqInfo)
|
||
|
DEBUG_ACACHE_UNINIT(CPageComponentManager)
|
||
|
DEBUG_ACACHE_UNINIT(CPageObject)
|
||
|
DEBUG_ACACHE_UNINIT(CRequest)
|
||
|
DEBUG_ACACHE_UNINIT(CRequestData)
|
||
|
DEBUG_ACACHE_UNINIT(CRequestHit)
|
||
|
DEBUG_ACACHE_UNINIT(CResponse)
|
||
|
DEBUG_ACACHE_UNINIT(CResponseBuffer)
|
||
|
DEBUG_ACACHE_UNINIT(CResponseData)
|
||
|
DEBUG_ACACHE_UNINIT(CScriptingNamespace)
|
||
|
DEBUG_ACACHE_UNINIT(CScriptingContext)
|
||
|
DEBUG_ACACHE_UNINIT(CServer)
|
||
|
DEBUG_ACACHE_UNINIT(CServerData)
|
||
|
DEBUG_ACACHE_UNINIT(CSession)
|
||
|
DEBUG_ACACHE_UNINIT(CSessionVariants)
|
||
|
DEBUG_ACACHE_UNINIT(CStringList)
|
||
|
DEBUG_ACACHE_UNINIT(CStringListElem)
|
||
|
DEBUG_ACACHE_UNINIT(CTemplate)
|
||
|
// DEBUG_ACACHE_UNINIT(CTemplate::CBuffer)
|
||
|
DEBUG_ACACHE_UNINIT(CTemplate::CFileMap)
|
||
|
DEBUG_ACACHE_UNINIT(CTypelibCacheEntry)
|
||
|
DEBUG_ACACHE_UNINIT(CVariantsIterator)
|
||
|
DEBUG_ACACHE_UNINIT(CViperActivity)
|
||
|
DEBUG_ACACHE_UNINIT(CViperAsyncRequest)
|
||
|
|
||
|
DEBUG_ACACHE_FSA_UNINIT(MemBlock128)
|
||
|
DEBUG_ACACHE_FSA_UNINIT(MemBlock256)
|
||
|
DEBUG_ACACHE_FSA_UNINIT(ResponseBuffer)
|
||
|
|
||
|
#ifdef DBG
|
||
|
DebugFilePrintf
|
||
|
(
|
||
|
SZ_MEMCLS_LOG_FILE,
|
||
|
"MEMCLS: ATQ allocation cache uninited.\n"
|
||
|
"MEMCLS: Total of %d ASP objects leaked.\n",
|
||
|
gs_cTotalObjectsLeaked
|
||
|
);
|
||
|
#endif
|
||
|
|
||
|
return S_OK;
|
||
|
}
|