123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604 |
- # === Fix the SM38 tracelogger ===
- # This patch is a squashed version of several patches that were adapted
- # to fix failing hunks.
- #
- # Applied in the following order, they are:
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1223767
- # Assertion failure: i < size_, at js/src/vm/TraceLoggingTypes.h:210
- # Also fix stop-information to make reduce.py work correctly.
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1227914
- # Limit the memory tracelogger can take.
- # This causes tracelogger to flush data to the disk regularly and prevents out of
- # memory issues if a lot of data gets logged.
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1155618
- # Fix tracelogger destructor that touches possibly uninitialised hash table.
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1223636
- # Don't treat extraTextId as containing only extra ids.
- # This fixes an assertion failure: id == nextTextId at js/src/vm/TraceLoggingGraph.cpp
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1227028
- # Fix when to keep the payload of a TraceLogger event.
- # This fixes an assertion failure: textId < uint32_t(1 << 31) at js/src/vm/TraceLoggingGraph.h
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1266649
- # Handle failing to add to pointermap gracefully.
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1280648
- # Don't cache based on pointers to movable GC things.
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1224123
- # Fix the use of LastEntryId in tracelogger.h.
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1231170
- # Use size in debugger instead of the current id to track last logged item.
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1221844
- # Move TraceLogger_Invalidation to LOG_ITEM.
- # Add some debug checks to logTimestamp.
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1255766
- # Also mark resizing of memory.
- # * https://bugzilla.mozilla.org/show_bug.cgi?id=1259403
- # Only increase capacity by multiples of 2.
- # Always make sure there are 3 free slots for events.
- # ===
- diff --git a/js/src/jit-test/tests/tracelogger/bug1231170.js b/js/src/jit-test/tests/tracelogger/bug1231170.js
- new file mode 100644
- index 0000000..023e93e
- --- /dev/null
- +++ b/js/src/jit-test/tests/tracelogger/bug1231170.js
- @@ -0,0 +1,3 @@
- +var du = new Debugger();
- +if (typeof du.drainTraceLogger === "function")
- + du.drainTraceLogger();
- diff --git a/js/src/jit-test/tests/tracelogger/bug1266649.js b/js/src/jit-test/tests/tracelogger/bug1266649.js
- new file mode 100644
- index 0000000..81ae7ad
- --- /dev/null
- +++ b/js/src/jit-test/tests/tracelogger/bug1266649.js
- @@ -0,0 +1,10 @@
- +
- +var du = new Debugger();
- +if (typeof du.setupTraceLogger === "function" &&
- + typeof oomTest === 'function')
- +{
- + du.setupTraceLogger({
- + Scripts: true
- + })
- + oomTest(() => function(){});
- +}
- diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp
- index 93e2fda..09049d6 100644
- --- a/js/src/jit/Ion.cpp
- +++ b/js/src/jit/Ion.cpp
- @@ -1055,6 +1055,8 @@ IonScript::Destroy(FreeOp* fop, IonScript* script)
-
- script->destroyCaches();
- script->unlinkFromRuntime(fop);
- + // Frees the potential event we have set.
- + script->traceLoggerScriptEvent_ = TraceLoggerEvent();
- fop->free_(script);
- }
-
- diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp
- index 26262fd..af7f313 100644
- --- a/js/src/vm/Debugger.cpp
- +++ b/js/src/vm/Debugger.cpp
- @@ -369,10 +369,10 @@ Debugger::Debugger(JSContext* cx, NativeObject* dbg)
- objects(cx),
- environments(cx),
- #ifdef NIGHTLY_BUILD
- - traceLoggerLastDrainedId(0),
- + traceLoggerLastDrainedSize(0),
- traceLoggerLastDrainedIteration(0),
- #endif
- - traceLoggerScriptedCallsLastDrainedId(0),
- + traceLoggerScriptedCallsLastDrainedSize(0),
- traceLoggerScriptedCallsLastDrainedIteration(0)
- {
- assertSameCompartment(cx, dbg);
- @@ -3907,9 +3907,9 @@ Debugger::drainTraceLogger(JSContext* cx, unsigned argc, Value* vp)
- size_t num;
- TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
- bool lostEvents = logger->lostEvents(dbg->traceLoggerLastDrainedIteration,
- - dbg->traceLoggerLastDrainedId);
- + dbg->traceLoggerLastDrainedSize);
- EventEntry* events = logger->getEventsStartingAt(&dbg->traceLoggerLastDrainedIteration,
- - &dbg->traceLoggerLastDrainedId,
- + &dbg->traceLoggerLastDrainedSize,
- &num);
-
- RootedObject array(cx, NewDenseEmptyArray(cx));
- @@ -4002,10 +4002,10 @@ Debugger::drainTraceLoggerScriptCalls(JSContext* cx, unsigned argc, Value* vp)
- size_t num;
- TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
- bool lostEvents = logger->lostEvents(dbg->traceLoggerScriptedCallsLastDrainedIteration,
- - dbg->traceLoggerScriptedCallsLastDrainedId);
- + dbg->traceLoggerScriptedCallsLastDrainedSize);
- EventEntry* events = logger->getEventsStartingAt(
- &dbg->traceLoggerScriptedCallsLastDrainedIteration,
- - &dbg->traceLoggerScriptedCallsLastDrainedId,
- + &dbg->traceLoggerScriptedCallsLastDrainedSize,
- &num);
-
- RootedObject array(cx, NewDenseEmptyArray(cx));
- diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h
- index 8cac36a..c92d685 100644
- --- a/js/src/vm/Debugger.h
- +++ b/js/src/vm/Debugger.h
- @@ -314,10 +314,10 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
- * lost events.
- */
- #ifdef NIGHTLY_BUILD
- - uint32_t traceLoggerLastDrainedId;
- + uint32_t traceLoggerLastDrainedSize;
- uint32_t traceLoggerLastDrainedIteration;
- #endif
- - uint32_t traceLoggerScriptedCallsLastDrainedId;
- + uint32_t traceLoggerScriptedCallsLastDrainedSize;
- uint32_t traceLoggerScriptedCallsLastDrainedIteration;
-
- class FrameRange;
- diff --git a/js/src/vm/TraceLogging.cpp b/js/src/vm/TraceLogging.cpp
- index 6715b36..9766a6f 100644
- --- a/js/src/vm/TraceLogging.cpp
- +++ b/js/src/vm/TraceLogging.cpp
- @@ -131,7 +131,7 @@ TraceLoggerThread::init()
- {
- if (!pointerMap.init())
- return false;
- - if (!extraTextId.init())
- + if (!textIdPayloads.init())
- return false;
- if (!events.init())
- return false;
- @@ -185,10 +185,10 @@ TraceLoggerThread::~TraceLoggerThread()
- graph = nullptr;
- }
-
- - for (TextIdHashMap::Range r = extraTextId.all(); !r.empty(); r.popFront())
- - js_delete(r.front().value());
- - extraTextId.finish();
- - pointerMap.finish();
- + if (textIdPayloads.initialized()) {
- + for (TextIdHashMap::Range r = textIdPayloads.all(); !r.empty(); r.popFront())
- + js_delete(r.front().value());
- + }
- }
-
- bool
- @@ -287,7 +287,7 @@ TraceLoggerThread::eventText(uint32_t id)
- if (id < TraceLogger_Last)
- return TLTextIdString(static_cast<TraceLoggerTextId>(id));
-
- - TextIdHashMap::Ptr p = extraTextId.lookup(id);
- + TextIdHashMap::Ptr p = textIdPayloads.lookup(id);
- MOZ_ASSERT(p);
-
- return p->value()->string();
- @@ -341,13 +341,15 @@ TraceLoggerThread::extractScriptDetails(uint32_t textId, const char** filename,
- TraceLoggerEventPayload*
- TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId textId)
- {
- - TextIdHashMap::AddPtr p = extraTextId.lookupForAdd(textId);
- - if (p)
- + TextIdHashMap::AddPtr p = textIdPayloads.lookupForAdd(textId);
- + if (p) {
- + MOZ_ASSERT(p->value()->textId() == textId); // Sanity check.
- return p->value();
- + }
-
- TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, (char*)nullptr);
-
- - if (!extraTextId.add(p, textId, payload))
- + if (!textIdPayloads.add(p, textId, payload))
- return nullptr;
-
- return payload;
- @@ -357,8 +359,10 @@ TraceLoggerEventPayload*
- TraceLoggerThread::getOrCreateEventPayload(const char* text)
- {
- PointerHashMap::AddPtr p = pointerMap.lookupForAdd((const void*)text);
- - if (p)
- + if (p) {
- + MOZ_ASSERT(p->value()->textId() < nextTextId); // Sanity check.
- return p->value();
- + }
-
- size_t len = strlen(text);
- char* str = js_pod_malloc<char>(len + 1);
- @@ -369,7 +373,7 @@ TraceLoggerThread::getOrCreateEventPayload(const char* text)
- MOZ_ASSERT(ret == len);
- MOZ_ASSERT(strlen(str) == len);
-
- - uint32_t textId = extraTextId.count() + TraceLogger_Last;
- + uint32_t textId = nextTextId;
-
- TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, str);
- if (!payload) {
- @@ -377,17 +381,19 @@ TraceLoggerThread::getOrCreateEventPayload(const char* text)
- return nullptr;
- }
-
- - if (!extraTextId.putNew(textId, payload)) {
- + if (!textIdPayloads.putNew(textId, payload)) {
- js_delete(payload);
- return nullptr;
- }
-
- - if (!pointerMap.add(p, text, payload))
- - return nullptr;
- -
- if (graph.get())
- graph->addTextId(textId, str);
-
- + nextTextId++;
- +
- + if (!pointerMap.add(p, text, payload))
- + return nullptr;
- +
- return payload;
- }
-
- @@ -407,9 +413,14 @@ TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type, const char* f
- if (!traceLoggerState->isTextIdEnabled(type))
- return getOrCreateEventPayload(type);
-
- - PointerHashMap::AddPtr p = pointerMap.lookupForAdd(ptr);
- - if (p)
- - return p->value();
- + PointerHashMap::AddPtr p;
- + if (ptr) {
- + p = pointerMap.lookupForAdd(ptr);
- + if (p) {
- + MOZ_ASSERT(p->value()->textId() < nextTextId); // Sanity check.
- + return p->value();
- + }
- + }
-
- // Compute the length of the string to create.
- size_t lenFilename = strlen(filename);
- @@ -428,24 +439,28 @@ TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type, const char* f
- MOZ_ASSERT(ret == len);
- MOZ_ASSERT(strlen(str) == len);
-
- - uint32_t textId = extraTextId.count() + TraceLogger_Last;
- + uint32_t textId = nextTextId;
- TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, str);
- if (!payload) {
- js_free(str);
- return nullptr;
- }
-
- - if (!extraTextId.putNew(textId, payload)) {
- + if (!textIdPayloads.putNew(textId, payload)) {
- js_delete(payload);
- return nullptr;
- }
-
- - if (!pointerMap.add(p, ptr, payload))
- - return nullptr;
- -
- if (graph.get())
- graph->addTextId(textId, str);
-
- + nextTextId++;
- +
- + if (ptr) {
- + if (!pointerMap.add(p, ptr, payload))
- + return nullptr;
- + }
- +
- return payload;
- }
-
- @@ -453,14 +468,14 @@ TraceLoggerEventPayload*
- TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type, JSScript* script)
- {
- return getOrCreateEventPayload(type, script->filename(), script->lineno(), script->column(),
- - script);
- + nullptr);
- }
-
- TraceLoggerEventPayload*
- TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type,
- const JS::ReadOnlyCompileOptions& script)
- {
- - return getOrCreateEventPayload(type, script.filename(), script.lineno, script.column, &script);
- + return getOrCreateEventPayload(type, script.filename(), script.lineno, script.column, nullptr);
- }
-
- void
- @@ -485,7 +500,7 @@ TraceLoggerThread::startEvent(uint32_t id)
- if (!traceLoggerState->isTextIdEnabled(id))
- return;
-
- - logTimestamp(id);
- + log(id);
- }
-
- void
- @@ -510,7 +525,7 @@ TraceLoggerThread::stopEvent(uint32_t id)
- if (!traceLoggerState->isTextIdEnabled(id))
- return;
-
- - logTimestamp(TraceLogger_Stop);
- + log(TraceLogger_Stop);
- }
-
- void
- @@ -522,23 +537,57 @@ TraceLoggerThread::logTimestamp(TraceLoggerTextId id)
- void
- TraceLoggerThread::logTimestamp(uint32_t id)
- {
- + MOZ_ASSERT(id > TraceLogger_LastTreeItem && id < TraceLogger_Last);
- + log(id);
- +}
- +
- +void
- +TraceLoggerThread::log(uint32_t id)
- +{
- if (enabled == 0)
- return;
-
- MOZ_ASSERT(traceLoggerState);
- - if (!events.ensureSpaceBeforeAdd()) {
- +
- + // We request for 3 items to add, since if we don't have enough room
- + // we record the time it took to make more place. To log this information
- + // we need 2 extra free entries.
- + if (!events.hasSpaceForAdd(3)) {
- uint64_t start = rdtsc() - traceLoggerState->startupTime;
-
- - if (graph.get())
- - graph->log(events);
- + if (!events.ensureSpaceBeforeAdd(3)) {
- + if (graph.get())
- + graph->log(events);
- +
- + iteration_++;
- + events.clear();
- +
- + // Remove the item in the pointerMap for which the payloads
- + // have no uses anymore
- + for (PointerHashMap::Enum e(pointerMap); !e.empty(); e.popFront()) {
- + if (e.front().value()->uses() != 0)
- + continue;
- +
- + TextIdHashMap::Ptr p = textIdPayloads.lookup(e.front().value()->textId());
- + MOZ_ASSERT(p);
- + textIdPayloads.remove(p);
- +
- + e.removeFront();
- + }
-
- - iteration_++;
- - events.clear();
- + // Free all payloads that have no uses anymore.
- + for (TextIdHashMap::Enum e(textIdPayloads); !e.empty(); e.popFront()) {
- + if (e.front().value()->uses() == 0) {
- + js_delete(e.front().value());
- + e.removeFront();
- + }
- + }
- + }
-
- // Log the time it took to flush the events as being from the
- // Tracelogger.
- if (graph.get()) {
- - MOZ_ASSERT(events.capacity() > 2);
- + MOZ_ASSERT(events.hasSpaceForAdd(2));
- EventEntry& entryStart = events.pushUninitialized();
- entryStart.time = start;
- entryStart.textId = TraceLogger_Internal;
- @@ -548,13 +597,6 @@ TraceLoggerThread::logTimestamp(uint32_t id)
- entryStop.textId = TraceLogger_Stop;
- }
-
- - // Free all TextEvents that have no uses anymore.
- - for (TextIdHashMap::Enum e(extraTextId); !e.empty(); e.popFront()) {
- - if (e.front().value()->uses() == 0) {
- - js_delete(e.front().value());
- - e.removeFront();
- - }
- - }
- }
-
- uint64_t time = rdtsc() - traceLoggerState->startupTime;
- @@ -956,3 +998,16 @@ TraceLoggerEvent::~TraceLoggerEvent()
- if (payload_)
- payload_->release();
- }
- +
- +TraceLoggerEvent&
- +TraceLoggerEvent::operator=(const TraceLoggerEvent& other)
- +{
- + if (hasPayload())
- + payload()->release();
- + if (other.hasPayload())
- + other.payload()->use();
- +
- + payload_ = other.payload_;
- +
- + return *this;
- +}
- diff --git a/js/src/vm/TraceLogging.h b/js/src/vm/TraceLogging.h
- index a124dcb..91a1eb0 100644
- --- a/js/src/vm/TraceLogging.h
- +++ b/js/src/vm/TraceLogging.h
- @@ -110,6 +110,9 @@ class TraceLoggerEvent {
- bool hasPayload() const {
- return !!payload_;
- }
- +
- + TraceLoggerEvent& operator=(const TraceLoggerEvent& other);
- + TraceLoggerEvent(const TraceLoggerEvent& event) = delete;
- };
-
- /**
- @@ -130,6 +133,10 @@ class TraceLoggerEventPayload {
- uses_(0)
- { }
-
- + ~TraceLoggerEventPayload() {
- + MOZ_ASSERT(uses_ == 0);
- + }
- +
- uint32_t textId() {
- return textId_;
- }
- @@ -166,7 +173,8 @@ class TraceLoggerThread
- mozilla::UniquePtr<TraceLoggerGraph> graph;
-
- PointerHashMap pointerMap;
- - TextIdHashMap extraTextId;
- + TextIdHashMap textIdPayloads;
- + uint32_t nextTextId;
-
- ContinuousSpace<EventEntry> events;
-
- @@ -181,6 +189,7 @@ class TraceLoggerThread
- : enabled(0),
- failed(false),
- graph(),
- + nextTextId(TraceLogger_Last),
- iteration_(0),
- top(nullptr)
- { }
- @@ -195,22 +204,22 @@ class TraceLoggerThread
- bool enable(JSContext* cx);
- bool disable();
-
- - // Given the previous iteration and lastEntryId, return an array of events
- + // Given the previous iteration and size, return an array of events
- // (there could be lost events). At the same time update the iteration and
- - // lastEntry and gives back how many events there are.
- - EventEntry* getEventsStartingAt(uint32_t* lastIteration, uint32_t* lastEntryId, size_t* num) {
- + // size and gives back how many events there are.
- + EventEntry* getEventsStartingAt(uint32_t* lastIteration, uint32_t* lastSize, size_t* num) {
- EventEntry* start;
- if (iteration_ == *lastIteration) {
- - MOZ_ASSERT(events.lastEntryId() >= *lastEntryId);
- - *num = events.lastEntryId() - *lastEntryId;
- - start = events.data() + *lastEntryId + 1;
- + MOZ_ASSERT(*lastSize <= events.size());
- + *num = events.size() - *lastSize;
- + start = events.data() + *lastSize;
- } else {
- - *num = events.lastEntryId() + 1;
- + *num = events.size();
- start = events.data();
- }
-
- *lastIteration = iteration_;
- - *lastEntryId = events.lastEntryId();
- + *lastSize = events.size();
- return start;
- }
-
- @@ -220,16 +229,16 @@ class TraceLoggerThread
- const char** lineno, size_t* lineno_len, const char** colno,
- size_t* colno_len);
-
- - bool lostEvents(uint32_t lastIteration, uint32_t lastEntryId) {
- + bool lostEvents(uint32_t lastIteration, uint32_t lastSize) {
- // If still logging in the same iteration, there are no lost events.
- if (lastIteration == iteration_) {
- - MOZ_ASSERT(lastEntryId <= events.lastEntryId());
- + MOZ_ASSERT(lastSize <= events.size());
- return false;
- }
-
- - // When proceeded to the next iteration and lastEntryId points to
- - // the maximum capacity there are no logs that are lost.
- - if (lastIteration + 1 == iteration_ && lastEntryId == events.capacity())
- + // If we are in a consecutive iteration we are only sure we didn't lose any events,
- + // when the lastSize equals the maximum size 'events' can get.
- + if (lastIteration == iteration_ - 1 && lastSize == events.maxSize())
- return false;
-
- return true;
- @@ -268,6 +277,7 @@ class TraceLoggerThread
- void stopEvent(uint32_t id);
- private:
- void stopEvent();
- + void log(uint32_t id);
-
- public:
- static unsigned offsetOfEnabled() {
- diff --git a/js/src/vm/TraceLoggingGraph.cpp b/js/src/vm/TraceLoggingGraph.cpp
- index d1b7f2e..a4eb273 100644
- --- a/js/src/vm/TraceLoggingGraph.cpp
- +++ b/js/src/vm/TraceLoggingGraph.cpp
- @@ -276,7 +276,7 @@ TraceLoggerGraph::flush()
- if (bytesWritten < tree.size())
- return false;
-
- - treeOffset += tree.lastEntryId();
- + treeOffset += tree.size();
- tree.clear();
- }
-
- @@ -359,7 +359,7 @@ TraceLoggerGraph::startEventInternal(uint32_t id, uint64_t timestamp)
-
- if (parent.lastChildId() == 0) {
- MOZ_ASSERT(!entry.hasChildren());
- - MOZ_ASSERT(parent.treeId() == tree.lastEntryId() + treeOffset);
- + MOZ_ASSERT(parent.treeId() == treeOffset + tree.size() - 1);
-
- if (!updateHasChildren(parent.treeId()))
- return false;
- diff --git a/js/src/vm/TraceLoggingTypes.h b/js/src/vm/TraceLoggingTypes.h
- index f1c9d0c..10b76d6 100644
- --- a/js/src/vm/TraceLoggingTypes.h
- +++ b/js/src/vm/TraceLoggingTypes.h
- @@ -21,7 +21,6 @@
- _(Internal) \
- _(Interpreter) \
- _(InlinedScripts) \
- - _(Invalidation) \
- _(IonCompilation) \
- _(IonCompilationPaused) \
- _(IonLinking) \
- @@ -60,6 +59,7 @@
-
- #define TRACELOGGER_LOG_ITEMS(_) \
- _(Bailout) \
- + _(Invalidation) \
- _(Disable) \
- _(Enable) \
- _(Stop)
- @@ -130,6 +130,9 @@ class ContinuousSpace {
- uint32_t size_;
- uint32_t capacity_;
-
- + // The maximum amount of ram memory a continuous space structure can take (in bytes).
- + static const uint32_t LIMIT = 200 * 1024 * 1024;
- +
- public:
- ContinuousSpace ()
- : data_(nullptr)
- @@ -151,6 +154,10 @@ class ContinuousSpace {
- data_ = nullptr;
- }
-
- + static uint32_t maxSize() {
- + return LIMIT / sizeof(T);
- + }
- +
- T* data() {
- return data_;
- }
- @@ -187,11 +194,14 @@ class ContinuousSpace {
- if (hasSpaceForAdd(count))
- return true;
-
- + // Limit the size of a continuous buffer.
- + if (size_ + count > maxSize())
- + return false;
- +
- uint32_t nCapacity = capacity_ * 2;
- - if (size_ + count > nCapacity)
- - nCapacity = size_ + count;
- - T* entries = (T*) js_realloc(data_, nCapacity * sizeof(T));
- + nCapacity = (nCapacity < maxSize()) ? nCapacity : maxSize();
-
- + T* entries = (T*) js_realloc(data_, nCapacity * sizeof(T));
- if (!entries)
- return false;
-
|