зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1020012 - Consolidate ScriptSources with the same source, r=luke.
This commit is contained in:
Родитель
1ad1ef7739
Коммит
3ba0ec8938
|
@ -351,7 +351,8 @@ struct RuntimeSizes
|
|||
macro(_, _, temporary) \
|
||||
macro(_, _, interpreterStack) \
|
||||
macro(_, _, mathCache) \
|
||||
macro(_, _, sourceDataCache) \
|
||||
macro(_, _, uncompressedSourceCache) \
|
||||
macro(_, _, compressedSourceSet) \
|
||||
macro(_, _, scriptData) \
|
||||
|
||||
RuntimeSizes()
|
||||
|
|
|
@ -1285,7 +1285,7 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext *cx, HandleFuncti
|
|||
JS_ASSERT(lazy->source()->hasSourceData());
|
||||
|
||||
// Parse and compile the script from source.
|
||||
SourceDataCache::AutoHoldEntry holder;
|
||||
UncompressedSourceCache::AutoHoldEntry holder;
|
||||
const jschar *chars = lazy->source()->chars(cx, holder);
|
||||
if (!chars)
|
||||
return false;
|
||||
|
|
|
@ -2949,7 +2949,7 @@ PurgeRuntime(JSRuntime *rt)
|
|||
rt->scopeCoordinateNameCache.purge();
|
||||
rt->newObjectCache.purge();
|
||||
rt->nativeIterCache.purge();
|
||||
rt->sourceDataCache.purge();
|
||||
rt->uncompressedSourceCache.purge();
|
||||
rt->evalCache.clear();
|
||||
|
||||
if (!rt->hasActiveCompilations())
|
||||
|
|
|
@ -1369,13 +1369,13 @@ JSScript::sourceData(JSContext *cx)
|
|||
return scriptSource()->substring(cx, sourceStart(), sourceEnd());
|
||||
}
|
||||
|
||||
SourceDataCache::AutoHoldEntry::AutoHoldEntry()
|
||||
UncompressedSourceCache::AutoHoldEntry::AutoHoldEntry()
|
||||
: cache_(nullptr), source_(nullptr), charsToFree_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SourceDataCache::AutoHoldEntry::holdEntry(SourceDataCache *cache, ScriptSource *source)
|
||||
UncompressedSourceCache::AutoHoldEntry::holdEntry(UncompressedSourceCache *cache, ScriptSource *source)
|
||||
{
|
||||
// Initialise the holder for a specific cache and script source. This will
|
||||
// hold on to the cached source chars in the event that the cache is purged.
|
||||
|
@ -1385,7 +1385,7 @@ SourceDataCache::AutoHoldEntry::holdEntry(SourceDataCache *cache, ScriptSource *
|
|||
}
|
||||
|
||||
void
|
||||
SourceDataCache::AutoHoldEntry::deferDelete(const jschar *chars)
|
||||
UncompressedSourceCache::AutoHoldEntry::deferDelete(const jschar *chars)
|
||||
{
|
||||
// Take ownership of source chars now the cache is being purged. Remove our
|
||||
// reference to the ScriptSource which might soon be destroyed.
|
||||
|
@ -1395,7 +1395,7 @@ SourceDataCache::AutoHoldEntry::deferDelete(const jschar *chars)
|
|||
charsToFree_ = chars;
|
||||
}
|
||||
|
||||
SourceDataCache::AutoHoldEntry::~AutoHoldEntry()
|
||||
UncompressedSourceCache::AutoHoldEntry::~AutoHoldEntry()
|
||||
{
|
||||
// The holder is going out of scope. If it has taken ownership of cached
|
||||
// chars then delete them, otherwise unregister ourself with the cache.
|
||||
|
@ -1409,7 +1409,7 @@ SourceDataCache::AutoHoldEntry::~AutoHoldEntry()
|
|||
}
|
||||
|
||||
void
|
||||
SourceDataCache::holdEntry(AutoHoldEntry &holder, ScriptSource *ss)
|
||||
UncompressedSourceCache::holdEntry(AutoHoldEntry &holder, ScriptSource *ss)
|
||||
{
|
||||
JS_ASSERT(!holder_);
|
||||
holder.holdEntry(this, ss);
|
||||
|
@ -1417,14 +1417,14 @@ SourceDataCache::holdEntry(AutoHoldEntry &holder, ScriptSource *ss)
|
|||
}
|
||||
|
||||
void
|
||||
SourceDataCache::releaseEntry(AutoHoldEntry &holder)
|
||||
UncompressedSourceCache::releaseEntry(AutoHoldEntry &holder)
|
||||
{
|
||||
JS_ASSERT(holder_ == &holder);
|
||||
holder_ = nullptr;
|
||||
}
|
||||
|
||||
const jschar *
|
||||
SourceDataCache::lookup(ScriptSource *ss, AutoHoldEntry &holder)
|
||||
UncompressedSourceCache::lookup(ScriptSource *ss, AutoHoldEntry &holder)
|
||||
{
|
||||
JS_ASSERT(!holder_);
|
||||
if (!map_)
|
||||
|
@ -1437,7 +1437,7 @@ SourceDataCache::lookup(ScriptSource *ss, AutoHoldEntry &holder)
|
|||
}
|
||||
|
||||
bool
|
||||
SourceDataCache::put(ScriptSource *ss, const jschar *str, AutoHoldEntry &holder)
|
||||
UncompressedSourceCache::put(ScriptSource *ss, const jschar *str, AutoHoldEntry &holder)
|
||||
{
|
||||
JS_ASSERT(!holder_);
|
||||
|
||||
|
@ -1461,7 +1461,7 @@ SourceDataCache::put(ScriptSource *ss, const jschar *str, AutoHoldEntry &holder)
|
|||
}
|
||||
|
||||
void
|
||||
SourceDataCache::purge()
|
||||
UncompressedSourceCache::purge()
|
||||
{
|
||||
if (!map_)
|
||||
return;
|
||||
|
@ -1481,7 +1481,7 @@ SourceDataCache::purge()
|
|||
}
|
||||
|
||||
size_t
|
||||
SourceDataCache::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
|
||||
UncompressedSourceCache::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
|
||||
{
|
||||
size_t n = 0;
|
||||
if (map_ && !map_->empty()) {
|
||||
|
@ -1495,7 +1495,7 @@ SourceDataCache::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
|
|||
}
|
||||
|
||||
const jschar *
|
||||
ScriptSource::chars(JSContext *cx, SourceDataCache::AutoHoldEntry &holder)
|
||||
ScriptSource::chars(JSContext *cx, UncompressedSourceCache::AutoHoldEntry &holder)
|
||||
{
|
||||
switch (dataType) {
|
||||
case DataUncompressed:
|
||||
|
@ -1503,7 +1503,7 @@ ScriptSource::chars(JSContext *cx, SourceDataCache::AutoHoldEntry &holder)
|
|||
|
||||
case DataCompressed: {
|
||||
#ifdef USE_ZLIB
|
||||
if (const jschar *decompressed = cx->runtime()->sourceDataCache.lookup(this, holder))
|
||||
if (const jschar *decompressed = cx->runtime()->uncompressedSourceCache.lookup(this, holder))
|
||||
return decompressed;
|
||||
|
||||
const size_t nbytes = sizeof(jschar) * (length_ + 1);
|
||||
|
@ -1520,7 +1520,7 @@ ScriptSource::chars(JSContext *cx, SourceDataCache::AutoHoldEntry &holder)
|
|||
|
||||
decompressed[length_] = 0;
|
||||
|
||||
if (!cx->runtime()->sourceDataCache.put(this, decompressed, holder)) {
|
||||
if (!cx->runtime()->uncompressedSourceCache.put(this, decompressed, holder)) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
js_free(decompressed);
|
||||
return nullptr;
|
||||
|
@ -1532,6 +1532,9 @@ ScriptSource::chars(JSContext *cx, SourceDataCache::AutoHoldEntry &holder)
|
|||
#endif
|
||||
}
|
||||
|
||||
case DataParent:
|
||||
return parent()->chars(cx, holder);
|
||||
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
@ -1541,7 +1544,7 @@ JSFlatString *
|
|||
ScriptSource::substring(JSContext *cx, uint32_t start, uint32_t stop)
|
||||
{
|
||||
JS_ASSERT(start <= stop);
|
||||
SourceDataCache::AutoHoldEntry holder;
|
||||
UncompressedSourceCache::AutoHoldEntry holder;
|
||||
const jschar *chars = this->chars(cx, holder);
|
||||
if (!chars)
|
||||
return nullptr;
|
||||
|
@ -1561,7 +1564,7 @@ ScriptSource::setSource(const jschar *chars, size_t length, bool ownsChars /* =
|
|||
}
|
||||
|
||||
void
|
||||
ScriptSource::setCompressedSource(void *raw, size_t nbytes)
|
||||
ScriptSource::setCompressedSource(JSRuntime *maybert, void *raw, size_t nbytes, HashNumber hash)
|
||||
{
|
||||
JS_ASSERT(dataType == DataMissing || dataType == DataUncompressed);
|
||||
if (dataType == DataUncompressed && ownsUncompressedChars())
|
||||
|
@ -1570,6 +1573,33 @@ ScriptSource::setCompressedSource(void *raw, size_t nbytes)
|
|||
dataType = DataCompressed;
|
||||
data.compressed.raw = raw;
|
||||
data.compressed.nbytes = nbytes;
|
||||
data.compressed.hash = hash;
|
||||
|
||||
if (maybert)
|
||||
updateCompressedSourceSet(maybert);
|
||||
}
|
||||
|
||||
void
|
||||
ScriptSource::updateCompressedSourceSet(JSRuntime *rt)
|
||||
{
|
||||
JS_ASSERT(dataType == DataCompressed);
|
||||
JS_ASSERT(!inCompressedSourceSet);
|
||||
|
||||
CompressedSourceSet::AddPtr p = rt->compressedSourceSet.lookupForAdd(this);
|
||||
if (p) {
|
||||
// There is another ScriptSource with the same compressed data.
|
||||
// Mark that ScriptSource as the parent and use it for all attempts to
|
||||
// get the source for this ScriptSource.
|
||||
ScriptSource *parent = *p;
|
||||
parent->incref();
|
||||
|
||||
js_free(compressedData());
|
||||
dataType = DataParent;
|
||||
data.parent = parent;
|
||||
} else {
|
||||
if (rt->compressedSourceSet.add(p, this))
|
||||
inCompressedSourceSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1688,6 +1718,7 @@ SourceCompressionTask::work()
|
|||
}
|
||||
}
|
||||
compressedBytes = comp.outWritten();
|
||||
compressedHash = CompressedSourceHasher::computeHash(compressed, compressedBytes);
|
||||
#else
|
||||
MOZ_CRASH();
|
||||
#endif
|
||||
|
@ -1701,6 +1732,8 @@ SourceCompressionTask::work()
|
|||
|
||||
ScriptSource::~ScriptSource()
|
||||
{
|
||||
JS_ASSERT_IF(inCompressedSourceSet, dataType == DataCompressed);
|
||||
|
||||
switch (dataType) {
|
||||
case DataUncompressed:
|
||||
if (ownsUncompressedChars())
|
||||
|
@ -1708,9 +1741,21 @@ ScriptSource::~ScriptSource()
|
|||
break;
|
||||
|
||||
case DataCompressed:
|
||||
// Script source references are only manipulated on the main thread,
|
||||
// except during off thread parsing when the source may be created
|
||||
// and used exclusively by the thread doing the parse. In this case the
|
||||
// ScriptSource might be destroyed while off the main thread, but it
|
||||
// will not have been added to the runtime's compressed source set
|
||||
// until the parse is finished on the main thread.
|
||||
if (inCompressedSourceSet)
|
||||
TlsPerThreadData.get()->runtimeFromMainThread()->compressedSourceSet.remove(this);
|
||||
js_free(compressedData());
|
||||
break;
|
||||
|
||||
case DataParent:
|
||||
parent()->decref();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1753,7 +1798,22 @@ ScriptSource::performXDR(XDRState<mode> *xdr)
|
|||
if (!xdr->codeUint32(&length_))
|
||||
return false;
|
||||
|
||||
uint32_t compressedLength = (dataType == DataCompressed) ? compressedBytes() : 0;
|
||||
uint32_t compressedLength;
|
||||
if (mode == XDR_ENCODE) {
|
||||
switch (dataType) {
|
||||
case DataUncompressed:
|
||||
compressedLength = 0;
|
||||
break;
|
||||
case DataCompressed:
|
||||
compressedLength = compressedBytes();
|
||||
break;
|
||||
case DataParent:
|
||||
compressedLength = parent()->compressedBytes();
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
if (!xdr->codeUint32(&compressedLength))
|
||||
return false;
|
||||
|
||||
|
@ -1776,11 +1836,25 @@ ScriptSource::performXDR(XDRState<mode> *xdr)
|
|||
}
|
||||
|
||||
if (compressedLength)
|
||||
setCompressedSource(p, compressedLength);
|
||||
setCompressedSource(xdr->cx()->runtime(), p, compressedLength,
|
||||
CompressedSourceHasher::computeHash(p, compressedLength));
|
||||
else
|
||||
setSource((const jschar *) p, length_);
|
||||
} else {
|
||||
void *p = compressedLength ? compressedData() : (void *) uncompressedChars();
|
||||
void *p;
|
||||
switch (dataType) {
|
||||
case DataUncompressed:
|
||||
p = (void *) uncompressedChars();
|
||||
break;
|
||||
case DataCompressed:
|
||||
p = compressedData();
|
||||
break;
|
||||
case DataParent:
|
||||
p = parent()->compressedData();
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
if (!xdr->codeBytes(p, byteLen))
|
||||
return false;
|
||||
}
|
||||
|
@ -3874,7 +3948,7 @@ LazyScriptHashPolicy::match(JSScript *script, const Lookup &lookup)
|
|||
return false;
|
||||
}
|
||||
|
||||
SourceDataCache::AutoHoldEntry holder;
|
||||
UncompressedSourceCache::AutoHoldEntry holder;
|
||||
|
||||
const jschar *scriptChars = script->scriptSource()->chars(cx, holder);
|
||||
if (!scriptChars)
|
||||
|
|
|
@ -339,7 +339,7 @@ typedef HashMap<JSScript *,
|
|||
|
||||
class ScriptSource;
|
||||
|
||||
class SourceDataCache
|
||||
class UncompressedSourceCache
|
||||
{
|
||||
typedef HashMap<ScriptSource *,
|
||||
const jschar *,
|
||||
|
@ -350,17 +350,17 @@ class SourceDataCache
|
|||
// Hold an entry in the source data cache and prevent it from being purged on GC.
|
||||
class AutoHoldEntry
|
||||
{
|
||||
SourceDataCache *cache_;
|
||||
UncompressedSourceCache *cache_;
|
||||
ScriptSource *source_;
|
||||
const jschar *charsToFree_;
|
||||
public:
|
||||
explicit AutoHoldEntry();
|
||||
~AutoHoldEntry();
|
||||
private:
|
||||
void holdEntry(SourceDataCache *cache, ScriptSource *source);
|
||||
void holdEntry(UncompressedSourceCache *cache, ScriptSource *source);
|
||||
void deferDelete(const jschar *chars);
|
||||
ScriptSource *source() const { return source_; }
|
||||
friend class SourceDataCache;
|
||||
friend class UncompressedSourceCache;
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -368,7 +368,7 @@ class SourceDataCache
|
|||
AutoHoldEntry *holder_;
|
||||
|
||||
public:
|
||||
SourceDataCache() : map_(nullptr), holder_(nullptr) {}
|
||||
UncompressedSourceCache() : map_(nullptr), holder_(nullptr) {}
|
||||
|
||||
const jschar *lookup(ScriptSource *ss, AutoHoldEntry &asp);
|
||||
bool put(ScriptSource *ss, const jschar *chars, AutoHoldEntry &asp);
|
||||
|
@ -396,7 +396,8 @@ class ScriptSource
|
|||
enum {
|
||||
DataMissing,
|
||||
DataUncompressed,
|
||||
DataCompressed
|
||||
DataCompressed,
|
||||
DataParent
|
||||
} dataType;
|
||||
|
||||
union {
|
||||
|
@ -408,7 +409,10 @@ class ScriptSource
|
|||
struct {
|
||||
void *raw;
|
||||
size_t nbytes;
|
||||
HashNumber hash;
|
||||
} compressed;
|
||||
|
||||
ScriptSource *parent;
|
||||
} data;
|
||||
|
||||
uint32_t length_;
|
||||
|
@ -450,6 +454,9 @@ class ScriptSource
|
|||
bool argumentsNotIncluded_:1;
|
||||
bool hasIntroductionOffset_:1;
|
||||
|
||||
// Whether this is in the runtime's set of compressed ScriptSources.
|
||||
bool inCompressedSourceSet:1;
|
||||
|
||||
public:
|
||||
explicit ScriptSource()
|
||||
: refs(0),
|
||||
|
@ -464,7 +471,8 @@ class ScriptSource
|
|||
introductionType_(nullptr),
|
||||
sourceRetrievable_(false),
|
||||
argumentsNotIncluded_(false),
|
||||
hasIntroductionOffset_(false)
|
||||
hasIntroductionOffset_(false),
|
||||
inCompressedSourceSet(false)
|
||||
{
|
||||
}
|
||||
~ScriptSource();
|
||||
|
@ -482,6 +490,7 @@ class ScriptSource
|
|||
void setSourceRetrievable() { sourceRetrievable_ = true; }
|
||||
bool sourceRetrievable() const { return sourceRetrievable_; }
|
||||
bool hasSourceData() const { return dataType != DataMissing; }
|
||||
bool hasCompressedSource() const { return dataType == DataCompressed; }
|
||||
size_t length() const {
|
||||
JS_ASSERT(hasSourceData());
|
||||
return length_;
|
||||
|
@ -490,7 +499,7 @@ class ScriptSource
|
|||
JS_ASSERT(hasSourceData());
|
||||
return argumentsNotIncluded_;
|
||||
}
|
||||
const jschar *chars(JSContext *cx, SourceDataCache::AutoHoldEntry &asp);
|
||||
const jschar *chars(JSContext *cx, UncompressedSourceCache::AutoHoldEntry &asp);
|
||||
JSFlatString *substring(JSContext *cx, uint32_t start, uint32_t stop);
|
||||
void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
|
||||
JS::ScriptSourceInfo *info) const;
|
||||
|
@ -515,8 +524,19 @@ class ScriptSource
|
|||
return data.compressed.nbytes;
|
||||
}
|
||||
|
||||
HashNumber compressedHash() const {
|
||||
JS_ASSERT(dataType == DataCompressed);
|
||||
return data.compressed.hash;
|
||||
}
|
||||
|
||||
ScriptSource *parent() const {
|
||||
JS_ASSERT(dataType == DataParent);
|
||||
return data.parent;
|
||||
}
|
||||
|
||||
void setSource(const jschar *chars, size_t length, bool ownsChars = true);
|
||||
void setCompressedSource(void *raw, size_t nbytes);
|
||||
void setCompressedSource(JSRuntime *maybert, void *raw, size_t nbytes, HashNumber hash);
|
||||
void updateCompressedSourceSet(JSRuntime *rt);
|
||||
bool ensureOwnsSource(ExclusiveContext *cx);
|
||||
|
||||
// XDR handling
|
||||
|
@ -581,6 +601,27 @@ class ScriptSourceHolder
|
|||
}
|
||||
};
|
||||
|
||||
struct CompressedSourceHasher
|
||||
{
|
||||
typedef ScriptSource *Lookup;
|
||||
|
||||
static HashNumber computeHash(const void *data, size_t nbytes) {
|
||||
return mozilla::HashBytes(data, nbytes);
|
||||
}
|
||||
|
||||
static HashNumber hash(const ScriptSource *ss) {
|
||||
return ss->compressedHash();
|
||||
}
|
||||
|
||||
static bool match(const ScriptSource *a, const ScriptSource *b) {
|
||||
return a->compressedBytes() == b->compressedBytes() &&
|
||||
a->compressedHash() == b->compressedHash() &&
|
||||
!memcmp(a->compressedData(), b->compressedData(), a->compressedBytes());
|
||||
}
|
||||
};
|
||||
|
||||
typedef HashSet<ScriptSource *, CompressedSourceHasher, SystemAllocPolicy> CompressedSourceSet;
|
||||
|
||||
class ScriptSourceObject : public JSObject
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -702,6 +702,11 @@ GlobalHelperThreadState::finishParseTask(JSContext *maybecx, JSRuntime *rt, void
|
|||
|
||||
// The NewScript hook needs to be called for all compiled scripts.
|
||||
CallNewScriptHookForAllScripts(cx, script);
|
||||
|
||||
// Update the compressed source table with the result. This is normally
|
||||
// called by setCompressedSource when compilation occurs on the main thread.
|
||||
if (script->scriptSource()->hasCompressedSource())
|
||||
script->scriptSource()->updateCompressedSourceSet(rt);
|
||||
}
|
||||
|
||||
return script;
|
||||
|
@ -990,7 +995,8 @@ SourceCompressionTask::complete()
|
|||
}
|
||||
|
||||
if (result == Success) {
|
||||
ss->setCompressedSource(compressed, compressedBytes);
|
||||
ss->setCompressedSource(cx->isJSContext() ? cx->asJSContext()->runtime() : nullptr,
|
||||
compressed, compressedBytes, compressedHash);
|
||||
|
||||
// Update memory accounting.
|
||||
cx->updateMallocCounter(ss->computedSizeOfData());
|
||||
|
|
|
@ -482,11 +482,12 @@ struct SourceCompressionTask
|
|||
} result;
|
||||
void *compressed;
|
||||
size_t compressedBytes;
|
||||
HashNumber compressedHash;
|
||||
|
||||
public:
|
||||
explicit SourceCompressionTask(ExclusiveContext *cx)
|
||||
: cx(cx), ss(nullptr), abort_(false),
|
||||
result(OOM), compressed(nullptr), compressedBytes(0)
|
||||
result(OOM), compressed(nullptr), compressedBytes(0), compressedHash(0)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
helperThread = nullptr;
|
||||
|
|
|
@ -312,6 +312,9 @@ JSRuntime::init(uint32_t maxbytes)
|
|||
if (!evalCache.init())
|
||||
return false;
|
||||
|
||||
if (!compressedSourceSet.init())
|
||||
return false;
|
||||
|
||||
/* The garbage collector depends on everything before this point being initialized. */
|
||||
gcInitialized = true;
|
||||
|
||||
|
@ -511,7 +514,9 @@ JSRuntime::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::Runtim
|
|||
|
||||
rtSizes->mathCache += mathCache_ ? mathCache_->sizeOfIncludingThis(mallocSizeOf) : 0;
|
||||
|
||||
rtSizes->sourceDataCache += sourceDataCache.sizeOfExcludingThis(mallocSizeOf);
|
||||
rtSizes->uncompressedSourceCache += uncompressedSourceCache.sizeOfExcludingThis(mallocSizeOf);
|
||||
|
||||
rtSizes->compressedSourceSet += compressedSourceSet.sizeOfExcludingThis(mallocSizeOf);
|
||||
|
||||
rtSizes->scriptData += scriptDataTable().sizeOfExcludingThis(mallocSizeOf);
|
||||
for (ScriptDataTable::Range r = scriptDataTable().all(); !r.empty(); r.popFront())
|
||||
|
|
|
@ -1091,10 +1091,11 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
js::ScopeCoordinateNameCache scopeCoordinateNameCache;
|
||||
js::NewObjectCache newObjectCache;
|
||||
js::NativeIterCache nativeIterCache;
|
||||
js::SourceDataCache sourceDataCache;
|
||||
js::UncompressedSourceCache uncompressedSourceCache;
|
||||
js::EvalCache evalCache;
|
||||
js::LazyScriptCache lazyScriptCache;
|
||||
|
||||
js::CompressedSourceSet compressedSourceSet;
|
||||
js::DateTimeInfo dateTimeInfo;
|
||||
|
||||
// Pool of maps used during parse/emit. This may be modified by threads
|
||||
|
|
|
@ -2374,9 +2374,13 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
|||
KIND_HEAP, rtStats.runtime.mathCache,
|
||||
"The math cache.");
|
||||
|
||||
RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/source-data-cache"),
|
||||
KIND_HEAP, rtStats.runtime.sourceDataCache,
|
||||
"The source data cache, which holds decompressed script source code.");
|
||||
RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/uncompressed-source-cache"),
|
||||
KIND_HEAP, rtStats.runtime.uncompressedSourceCache,
|
||||
"The uncompressed source code cache.");
|
||||
|
||||
RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/compressed-source-sets"),
|
||||
KIND_HEAP, rtStats.runtime.compressedSourceSet,
|
||||
"The table indexing compressed source code in the runtime.");
|
||||
|
||||
RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/script-data"),
|
||||
KIND_HEAP, rtStats.runtime.scriptData,
|
||||
|
|
Загрузка…
Ссылка в новой задаче