Bug 1334307 - do not allocate in GenericPrinter::vprintf; r=nbp

MozReview-Commit-ID: Ibcv21s3tU0

--HG--
extra : rebase_source : 5a53e0b696c0c167976026c160c17b96852032b7
This commit is contained in:
Tom Tromey 2017-02-28 10:00:56 -07:00
parent 0f173417cb
commit c832a17763
2 changed files with 31 additions and 96 deletions

View File

@ -7,19 +7,42 @@
#include "vm/Printer.h"
#include "mozilla/PodOperations.h"
#include "mozilla/Printf.h"
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include "jscntxt.h"
#include "jsprf.h"
#include "jsutil.h"
#include "ds/LifoAlloc.h"
using mozilla::PodCopy;
namespace
{
class GenericPrinterPrintfTarget : public mozilla::PrintfTarget
{
public:
explicit GenericPrinterPrintfTarget(js::GenericPrinter& p)
: printer(p)
{
}
bool append(const char* sp, size_t len) {
return printer.put(sp, len);
}
private:
js::GenericPrinter& printer;
};
}
namespace js {
GenericPrinter::GenericPrinter()
@ -58,15 +81,12 @@ GenericPrinter::vprintf(const char* fmt, va_list ap)
if (strchr(fmt, '%') == nullptr)
return put(fmt);
char* bp;
bp = JS_vsmprintf(fmt, ap); /* XXX vsaprintf */
if (!bp) {
GenericPrinterPrintfTarget printer(*this);
if (!printer.vprint(fmt, ap)) {
reportOutOfMemory();
return false;
}
bool r = put(bp);
js_free(bp);
return r;
return true;
}
const size_t Sprinter::DefaultSize = 64;
@ -197,25 +217,6 @@ Sprinter::put(const char* s, size_t len)
return true;
}
bool
Sprinter::vprintf(const char* fmt, va_list ap)
{
InvariantChecker ic(this);
do {
va_list aq;
va_copy(aq, ap);
int i = vsnprintf(base + offset, size - offset, fmt, aq);
va_end(aq);
if (i > -1 && (size_t) i < size - offset) {
offset += i;
return true;
}
} while (realloc_(size * 2));
return false;
}
bool
Sprinter::putString(JSString* s)
{
@ -264,14 +265,10 @@ Sprinter::jsprintf(const char* format, ...)
va_list ap;
va_start(ap, format);
UniquePtr<char, JS::FreePolicy> chars(JS_vsmprintf(format, ap)); /* XXX vsaprintf */
bool r = vprintf(format, ap);
va_end(ap);
if (!chars) {
reportOutOfMemory();
return false;
}
return put(chars.get());
return r;
}
const char js_EscapeMap[] = {
@ -452,29 +449,6 @@ Fprinter::put(const char* s, size_t len)
return true;
}
bool
Fprinter::printf(const char* fmt, ...)
{
MOZ_ASSERT(file_);
va_list ap;
va_start(ap, fmt);
bool r = vfprintf(file_, fmt, ap);
if (!r)
reportOutOfMemory();
va_end(ap);
return r;
}
bool
Fprinter::vprintf(const char* fmt, va_list ap)
{
MOZ_ASSERT(file_);
bool r = vfprintf(file_, fmt, ap);
if (!r)
reportOutOfMemory();
return r;
}
LSprinter::LSprinter(LifoAlloc* lifoAlloc)
: alloc_(lifoAlloc),
head_(nullptr),
@ -575,34 +549,6 @@ LSprinter::put(const char* s, size_t len)
return true;
}
bool
LSprinter::printf(const char* fmt, ...)
{
va_list va;
va_start(va, fmt);
bool r = vprintf(fmt, va);
va_end(va);
return r;
}
bool
LSprinter::vprintf(const char* fmt, va_list ap)
{
// Simple shortcut to avoid allocating strings.
if (strchr(fmt, '%') == nullptr)
return put(fmt);
char* bp;
bp = JS_vsmprintf(fmt, ap); /* XXX vsaprintf */
if (!bp) {
reportOutOfMemory();
return false;
}
bool r = put(bp);
js_free(bp);
return r;
}
void
LSprinter::reportOutOfMemory()
{

View File

@ -44,8 +44,8 @@ class GenericPrinter
}
// Prints a formatted string into the buffer.
virtual bool printf(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
virtual bool vprintf(const char* fmt, va_list ap);
bool printf(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
bool vprintf(const char* fmt, va_list ap);
// Report that a string operation failed to get the memory it requested. The
// first call to this function calls JS_ReportOutOfMemory, and sets this
@ -118,9 +118,6 @@ class Sprinter final : public GenericPrinter
// OOM).
MOZ_MUST_USE bool jsprintf(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
// Prints a formatted string into the buffer.
virtual bool vprintf(const char* fmt, va_list ap) override;
bool putString(JSString* str);
ptrdiff_t getOffset() const;
@ -156,10 +153,6 @@ class Fprinter final : public GenericPrinter
// return true on success, false on failure.
virtual bool put(const char* s, size_t len) override;
using GenericPrinter::put; // pick up |inline bool put(const char* s);|
// Prints a formatted string into the buffer.
virtual bool printf(const char* fmt, ...) override MOZ_FORMAT_PRINTF(2, 3);
virtual bool vprintf(const char* fmt, va_list ap) override;
};
// LSprinter, is similar to Sprinter except that instead of using an
@ -203,10 +196,6 @@ class LSprinter final : public GenericPrinter
virtual bool put(const char* s, size_t len) override;
using GenericPrinter::put; // pick up |inline bool put(const char* s);|
// Prints a formatted string into the buffer.
virtual bool printf(const char* fmt, ...) override MOZ_FORMAT_PRINTF(2, 3);
virtual bool vprintf(const char* fmt, va_list ap) override;
// Report that a string operation failed to get the memory it requested. The
// first call to this function calls JS_ReportOutOfMemory, and sets this
// Sprinter's outOfMemory flag; subsequent calls do nothing.