mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 6b6054736cb2
This commit is contained in:
parent
0a1ab2b3e9
commit
928a6b8a25
@ -40,7 +40,6 @@
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsArray.h"
|
||||
|
||||
@ -55,13 +54,103 @@
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include <windows.h>
|
||||
#define NS_MEMORY_FLUSHER
|
||||
#elif defined (NS_OSSO)
|
||||
#include <osso-mem.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
const char* kHighMark = "/sys/kernel/high_watermark";
|
||||
#else
|
||||
// Need to implement the nsIMemory::IsLowMemory() predicate
|
||||
#undef NS_MEMORY_FLUSHER
|
||||
#endif
|
||||
|
||||
#ifdef NS_MEMORY_FLUSHER
|
||||
#include "nsITimer.h"
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Define NS_OUT_OF_MEMORY_TESTER if you want to force memory failures
|
||||
|
||||
#ifdef DEBUG_xwarren
|
||||
#define NS_OUT_OF_MEMORY_TESTER
|
||||
#endif
|
||||
|
||||
#ifdef NS_OUT_OF_MEMORY_TESTER
|
||||
|
||||
// flush memory one in this number of times:
|
||||
#define NS_FLUSH_FREQUENCY 100000
|
||||
|
||||
// fail allocation one in this number of flushes:
|
||||
#define NS_FAIL_FREQUENCY 10
|
||||
|
||||
PRUint32 gFlushFreq = 0;
|
||||
PRUint32 gFailFreq = 0;
|
||||
|
||||
static void*
|
||||
mallocator(PRSize size, PRUint32& counter, PRUint32 max)
|
||||
{
|
||||
if (counter++ >= max) {
|
||||
counter = 0;
|
||||
NS_ASSERTION(0, "about to fail allocation... watch out");
|
||||
return nsnull;
|
||||
}
|
||||
return PR_Malloc(size);
|
||||
}
|
||||
|
||||
static void*
|
||||
reallocator(void* ptr, PRSize size, PRUint32& counter, PRUint32 max)
|
||||
{
|
||||
if (counter++ >= max) {
|
||||
counter = 0;
|
||||
NS_ASSERTION(0, "about to fail reallocation... watch out");
|
||||
return nsnull;
|
||||
}
|
||||
return PR_Realloc(ptr, size);
|
||||
}
|
||||
|
||||
#define MALLOC1(s) mallocator(s, gFlushFreq, NS_FLUSH_FREQUENCY)
|
||||
#define REALLOC1(p, s) reallocator(p, s, gFlushFreq, NS_FLUSH_FREQUENCY)
|
||||
|
||||
#else
|
||||
|
||||
#define MALLOC1(s) PR_Malloc(s)
|
||||
#define REALLOC1(p, s) PR_Realloc(p, s)
|
||||
|
||||
#endif // NS_OUT_OF_MEMORY_TESTER
|
||||
|
||||
#if defined(XDEBUG_waterson)
|
||||
#define NS_TEST_MEMORY_FLUSHER
|
||||
#endif
|
||||
|
||||
#ifdef NS_MEMORY_FLUSHER
|
||||
/**
|
||||
* A class that is used to periodically check the status of the system,
|
||||
* determine if too much memory is in use, and if so, trigger a "memory flush".
|
||||
*/
|
||||
class MemoryFlusher : public nsITimerCallback
|
||||
{
|
||||
public:
|
||||
// We don't use the generic macros because we are a special static object
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aResult);
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void) { return 2; }
|
||||
NS_IMETHOD_(nsrefcnt) Release(void) { return 1; }
|
||||
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
nsresult Init();
|
||||
void StopAndJoin();
|
||||
|
||||
private:
|
||||
static PRIntervalTime sTimeout;
|
||||
static PRLock* sLock;
|
||||
static PRCondVar* sCVar;
|
||||
|
||||
enum {
|
||||
kTimeout = 60000 // milliseconds
|
||||
};
|
||||
};
|
||||
|
||||
static MemoryFlusher sGlobalMemoryFlusher;
|
||||
|
||||
#endif // NS_MEMORY_FLUSHER
|
||||
|
||||
static nsMemoryImpl sGlobalMemory;
|
||||
|
||||
@ -103,22 +192,32 @@ nsMemoryImpl::IsLowMemory(PRBool *result)
|
||||
GlobalMemoryStatus(&stat);
|
||||
*result = ((float)stat.dwAvailPageFile / stat.dwTotalPageFile) < 0.1;
|
||||
#elif defined(NS_OSSO)
|
||||
|
||||
int fd = open (kHighMark, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
*result = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
int c = 0;
|
||||
read (fd, &c, 1);
|
||||
close(fd);
|
||||
*result = (c == '1');
|
||||
osso_mem_usage_t usage;
|
||||
osso_mem_get_usage(&usage);
|
||||
|
||||
// According to the docs, low memory limit isn't set if it is
|
||||
// zero, or if it is greater than 100%.
|
||||
if (usage.low == 0 || usage.low > usage.total)
|
||||
*result = PR_FALSE;
|
||||
else
|
||||
*result = (PRBool) usage.low <= usage.used;
|
||||
#else
|
||||
*result = PR_FALSE;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ nsresult
|
||||
nsMemoryImpl::InitFlusher()
|
||||
{
|
||||
#ifdef NS_MEMORY_FLUSHER
|
||||
return sGlobalMemoryFlusher.Init();
|
||||
#else
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*static*/ nsresult
|
||||
nsMemoryImpl::Create(nsISupports* outer, const nsIID& aIID, void **aResult)
|
||||
{
|
||||
@ -158,42 +257,12 @@ nsMemoryImpl::FlushMemory(const PRUnichar* aReason, PRBool aImmediate)
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef GET_OOM_STATS
|
||||
static long getUsedMemory()
|
||||
{
|
||||
#ifdef NS_OSSO
|
||||
osso_mem_usage_t usage;
|
||||
osso_mem_get_usage(&usage);
|
||||
return usage.used;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsMemoryImpl::RunFlushers(const PRUnichar* aReason)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> os = do_GetService("@mozilla.org/observer-service;1");
|
||||
if (os) {
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> theEnum;
|
||||
os->EnumerateObservers("memory-pressure", getter_AddRefs(theEnum));
|
||||
|
||||
nsCOMPtr<nsIObserver> elem;
|
||||
PRBool loop;
|
||||
while (NS_SUCCEEDED(theEnum->HasMoreElements(&loop)) && loop) {
|
||||
theEnum->GetNext(getter_AddRefs(elem));
|
||||
|
||||
#ifdef GET_OOM_STATS
|
||||
long before = getUsedMemory();
|
||||
#endif
|
||||
elem->Observe(this, "memory-pressure", aReason);
|
||||
|
||||
#ifdef GET_OOM_STATS
|
||||
printf("Memory Purged: %ld\n", before - getUsedMemory());
|
||||
#endif
|
||||
}
|
||||
os->NotifyObservers(this, "memory-pressure", aReason);
|
||||
}
|
||||
|
||||
sIsFlushing = 0;
|
||||
@ -221,7 +290,7 @@ nsMemoryImpl::sFlushEvent;
|
||||
XPCOM_API(void*)
|
||||
NS_Alloc(PRSize size)
|
||||
{
|
||||
void* result = PR_Malloc(size);
|
||||
void* result = MALLOC1(size);
|
||||
if (! result) {
|
||||
// Request an asynchronous flush
|
||||
sGlobalMemory.FlushMemory(NS_LITERAL_STRING("alloc-failure").get(), PR_FALSE);
|
||||
@ -232,7 +301,7 @@ NS_Alloc(PRSize size)
|
||||
XPCOM_API(void*)
|
||||
NS_Realloc(void* ptr, PRSize size)
|
||||
{
|
||||
void* result = PR_Realloc(ptr, size);
|
||||
void* result = REALLOC1(ptr, size);
|
||||
if (! result && size != 0) {
|
||||
// Request an asynchronous flush
|
||||
sGlobalMemory.FlushMemory(NS_LITERAL_STRING("alloc-failure").get(), PR_FALSE);
|
||||
@ -246,6 +315,43 @@ NS_Free(void* ptr)
|
||||
PR_Free(ptr);
|
||||
}
|
||||
|
||||
#ifdef NS_MEMORY_FLUSHER
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE1(MemoryFlusher, nsITimerCallback)
|
||||
|
||||
NS_IMETHODIMP
|
||||
MemoryFlusher::Notify(nsITimer *timer)
|
||||
{
|
||||
PRBool isLowMemory;
|
||||
sGlobalMemory.IsLowMemory(&isLowMemory);
|
||||
|
||||
#ifdef NS_TEST_MEMORY_FLUSHER
|
||||
// Fire the flusher *every* time
|
||||
isLowMemory = PR_TRUE;
|
||||
#endif
|
||||
|
||||
if (isLowMemory)
|
||||
sGlobalMemory.FlushMemory(NS_LITERAL_STRING("low-memory").get(),
|
||||
PR_FALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MemoryFlusher::Init()
|
||||
{
|
||||
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
NS_ENSURE_STATE(timer);
|
||||
|
||||
// There is no need to keep a reference to the timer object because we
|
||||
// don't need to kill the timer. It will be killed automatically when
|
||||
// XPCOM is shutdown.
|
||||
|
||||
return timer->InitWithCallback(this, kTimeout,
|
||||
nsITimer::TYPE_REPEATING_SLACK);
|
||||
}
|
||||
|
||||
#endif // NS_MEMORY_FLUSHER
|
||||
|
||||
nsresult
|
||||
NS_GetMemoryManager(nsIMemory* *result)
|
||||
{
|
||||
|
@ -55,6 +55,7 @@ public:
|
||||
|
||||
NS_DECL_NSIMEMORY
|
||||
|
||||
static NS_HIDDEN_(nsresult) InitFlusher();
|
||||
static NS_METHOD Create(nsISupports* outer,
|
||||
const nsIID& aIID, void **aResult);
|
||||
|
||||
|
@ -660,6 +660,9 @@ NS_InitXPCOM3(nsIServiceManager* *result,
|
||||
// to the directory service.
|
||||
nsDirectoryService::gService->RegisterCategoryProviders();
|
||||
|
||||
// Initialize memory flusher
|
||||
nsMemoryImpl::InitFlusher();
|
||||
|
||||
// Notify observers of xpcom autoregistration start
|
||||
NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY,
|
||||
nsnull,
|
||||
|
Loading…
Reference in New Issue
Block a user