mirror of
https://github.com/UOX3DevTeam/UOX3
synced 2026-08-13 12:27:04 -04:00
111 lines
2.7 KiB
C++
111 lines
2.7 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: set ts=8 sw=4 et tw=99:
|
|
*
|
|
* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/licenses/publicdomain/
|
|
* Contributor: Igor Bukanov
|
|
*/
|
|
|
|
#include "tests.h"
|
|
#include "jsgcchunk.h"
|
|
#include "jscntxt.h"
|
|
|
|
/* We allow to allocate only single chunk. */
|
|
|
|
class CustomGCChunkAllocator: public js::GCChunkAllocator {
|
|
public:
|
|
CustomGCChunkAllocator() : pool(NULL) {}
|
|
void *pool;
|
|
|
|
private:
|
|
|
|
virtual void *doAlloc() {
|
|
if (!pool)
|
|
return NULL;
|
|
void *chunk = pool;
|
|
pool = NULL;
|
|
return chunk;
|
|
}
|
|
|
|
virtual void doFree(void *chunk) {
|
|
JS_ASSERT(!pool);
|
|
pool = chunk;
|
|
}
|
|
};
|
|
|
|
static CustomGCChunkAllocator customGCChunkAllocator;
|
|
|
|
static unsigned errorCount = 0;
|
|
|
|
static void
|
|
ErrorCounter(JSContext *cx, const char *message, JSErrorReport *report)
|
|
{
|
|
++errorCount;
|
|
}
|
|
|
|
BEGIN_TEST(testGCChunkAlloc)
|
|
{
|
|
JS_SetErrorReporter(cx, ErrorCounter);
|
|
|
|
jsvalRoot root(cx);
|
|
|
|
/*
|
|
* We loop until out-of-memory happens during the chunk allocation. But
|
|
* we have to disable the jit since it cannot tolerate OOM during the
|
|
* chunk allocation.
|
|
*/
|
|
JS_ToggleOptions(cx, JSOPTION_JIT);
|
|
|
|
static const char source[] =
|
|
"var max = 0; (function() {"
|
|
" var array = [];"
|
|
" for (; ; ++max)"
|
|
" array.push({});"
|
|
"})();";
|
|
JSBool ok = JS_EvaluateScript(cx, global, source, strlen(source), "", 1,
|
|
root.addr());
|
|
|
|
/* Check that we get OOM. */
|
|
CHECK(!ok);
|
|
CHECK(!JS_IsExceptionPending(cx));
|
|
CHECK(errorCount == 1);
|
|
CHECK(!customGCChunkAllocator.pool);
|
|
JS_GC(cx);
|
|
JS_ToggleOptions(cx, JSOPTION_JIT);
|
|
EVAL("(function() {"
|
|
" var array = [];"
|
|
" for (var i = max >> 1; i != 0;) {"
|
|
" --i;"
|
|
" array.push({});"
|
|
" }"
|
|
"})();", root.addr());
|
|
CHECK(errorCount == 1);
|
|
return true;
|
|
}
|
|
|
|
virtual JSRuntime * createRuntime() {
|
|
/*
|
|
* To test failure of chunk allocation allow to use GC twice the memory
|
|
* the single chunk contains.
|
|
*/
|
|
JSRuntime *rt = JS_NewRuntime(2 * js::GC_CHUNK_SIZE);
|
|
if (!rt)
|
|
return NULL;
|
|
|
|
customGCChunkAllocator.pool = js::AllocGCChunk();
|
|
JS_ASSERT(customGCChunkAllocator.pool);
|
|
|
|
rt->setCustomGCChunkAllocator(&customGCChunkAllocator);
|
|
return rt;
|
|
}
|
|
|
|
virtual void destroyRuntime() {
|
|
JS_DestroyRuntime(rt);
|
|
|
|
/* We should get the initial chunk back at this point. */
|
|
JS_ASSERT(customGCChunkAllocator.pool);
|
|
js::FreeGCChunk(customGCChunkAllocator.pool);
|
|
customGCChunkAllocator.pool = NULL;
|
|
}
|
|
|
|
END_TEST(testGCChunkAlloc)
|