mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 12:13:22 +00:00
Bug 676700 - Slightly speed up js::IndexToId by converting directly to atom, not to string and then to atom. r=luke
--HG-- extra : rebase_source : d352929e4002f285670448e4515bea404f2cf88f
This commit is contained in:
parent
30dcca107a
commit
f0a15f8ce0
@ -42,6 +42,9 @@
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mozilla/RangedPtr.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
@ -665,6 +668,27 @@ js_InitAtomMap(JSContext *cx, JSAtomMap *map, AtomIndexMap *indices)
|
||||
}
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
bool
|
||||
IndexToIdSlow(JSContext *cx, uint32 index, jsid *idp)
|
||||
{
|
||||
JS_ASSERT(index > JSID_INT_MAX);
|
||||
|
||||
jschar buf[UINT32_CHAR_BUFFER_LENGTH];
|
||||
RangedPtr<jschar> end(buf + JS_ARRAY_LENGTH(buf), buf, buf + JS_ARRAY_LENGTH(buf));
|
||||
RangedPtr<jschar> start = BackfillIndexInCharBuffer(index, end);
|
||||
|
||||
JSAtom *atom = js_AtomizeChars(cx, start.get(), end - start);
|
||||
if (!atom)
|
||||
return false;
|
||||
|
||||
*idp = ATOM_TO_JSID(atom);
|
||||
JS_ASSERT(js_CheckForStringIndex(*idp) == *idp);
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/* JSBOXEDWORD_INT_MAX as a string */
|
||||
#define JSBOXEDWORD_INT_MAX_STRING "1073741823"
|
||||
|
@ -40,6 +40,8 @@
|
||||
#ifndef jsatominlines_h___
|
||||
#define jsatominlines_h___
|
||||
|
||||
#include "mozilla/RangedPtr.h"
|
||||
|
||||
#include "jsatom.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsobj.h"
|
||||
@ -133,6 +135,37 @@ js_Int32ToId(JSContext* cx, int32 index, jsid* id)
|
||||
|
||||
namespace js {
|
||||
|
||||
static const size_t UINT32_CHAR_BUFFER_LENGTH = sizeof("4294967295") - 1;
|
||||
|
||||
/*
|
||||
* Write out character representing |index| to the memory just before |end|.
|
||||
* Thus |*end| is not touched, but |end[-1]| and earlier are modified as
|
||||
* appropriate. There must be at least UINT32_CHAR_BUFFER_LENGTH elements
|
||||
* before |end| to avoid buffer underflow. The start of the characters written
|
||||
* is returned and is necessarily before |end|.
|
||||
*/
|
||||
template <typename T>
|
||||
inline mozilla::RangedPtr<T>
|
||||
BackfillIndexInCharBuffer(uint32 index, mozilla::RangedPtr<T> end)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Assert that the buffer we're filling will hold as many characters as we
|
||||
* could write out, by dereferencing the index that would hold the most
|
||||
* significant digit.
|
||||
*/
|
||||
(void) *(end - UINT32_CHAR_BUFFER_LENGTH);
|
||||
#endif
|
||||
|
||||
do {
|
||||
uint32 next = index / 10, digit = index % 10;
|
||||
*--end = '0' + digit;
|
||||
index = next;
|
||||
} while (index > 0);
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IndexToId(JSContext *cx, uint32 index, jsid *idp)
|
||||
{
|
||||
@ -141,15 +174,8 @@ IndexToId(JSContext *cx, uint32 index, jsid *idp)
|
||||
return true;
|
||||
}
|
||||
|
||||
JSString *str = js_NumberToString(cx, index);
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
JSAtom *atom = js_AtomizeString(cx, str);
|
||||
if (!atom)
|
||||
return false;
|
||||
*idp = ATOM_TO_JSID(atom);
|
||||
return true;
|
||||
extern bool IndexToIdSlow(JSContext *cx, uint32 index, jsid *idp);
|
||||
return IndexToIdSlow(cx, index, idp);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JSString *
|
||||
|
@ -75,6 +75,7 @@
|
||||
#include "jsvector.h"
|
||||
#include "jslibmath.h"
|
||||
|
||||
#include "jsatominlines.h"
|
||||
#include "jsinterpinlines.h"
|
||||
#include "jsnuminlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
@ -650,23 +651,17 @@ js_IntToString(JSContext *cx, int32 si)
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
/* +1, since MAX_LENGTH does not count the null char. */
|
||||
JS_STATIC_ASSERT(JSShortString::MAX_LENGTH + 1 >= sizeof("-2147483648"));
|
||||
jschar *storage = str->inlineStorageBeforeInit();
|
||||
RangedPtr<jschar> end(storage + JSShortString::MAX_SHORT_LENGTH,
|
||||
storage, JSShortString::MAX_SHORT_LENGTH + 1);
|
||||
*end = '\0';
|
||||
|
||||
jschar *end = str->inlineStorageBeforeInit() + JSShortString::MAX_SHORT_LENGTH;
|
||||
jschar *cp = end;
|
||||
*cp = 0;
|
||||
|
||||
do {
|
||||
jsuint newui = ui / 10, digit = ui % 10; /* optimizers are our friends */
|
||||
*--cp = '0' + digit;
|
||||
ui = newui;
|
||||
} while (ui != 0);
|
||||
RangedPtr<jschar> start = BackfillIndexInCharBuffer(ui, end);
|
||||
|
||||
if (si < 0)
|
||||
*--cp = '-';
|
||||
*--start = '-';
|
||||
|
||||
str->initAtOffsetInBuffer(cp, end - cp);
|
||||
str->initAtOffsetInBuffer(start.get(), end - start);
|
||||
|
||||
c->dtoaCache.cache(10, si, str);
|
||||
return str;
|
||||
@ -676,25 +671,15 @@ js_IntToString(JSContext *cx, int32 si)
|
||||
static char *
|
||||
IntToCString(ToCStringBuf *cbuf, jsint i, jsint base = 10)
|
||||
{
|
||||
char *cp;
|
||||
jsuint u;
|
||||
jsuint u = (i < 0) ? -i : i;
|
||||
|
||||
u = (i < 0) ? -i : i;
|
||||
RangedPtr<char> cp(cbuf->sbuf + cbuf->sbufSize - 1, cbuf->sbuf, cbuf->sbufSize);
|
||||
*cp = '\0';
|
||||
|
||||
cp = cbuf->sbuf + cbuf->sbufSize; /* one past last buffer cell */
|
||||
*--cp = '\0'; /* null terminate the string to be */
|
||||
|
||||
/*
|
||||
* Build the string from behind. We use multiply and subtraction
|
||||
* instead of modulus because that's much faster.
|
||||
*/
|
||||
/* Build the string from behind. */
|
||||
switch (base) {
|
||||
case 10:
|
||||
do {
|
||||
jsuint newu = u / 10;
|
||||
*--cp = (char)(u - newu * 10) + '0';
|
||||
u = newu;
|
||||
} while (u != 0);
|
||||
cp = BackfillIndexInCharBuffer(u, cp);
|
||||
break;
|
||||
case 16:
|
||||
do {
|
||||
@ -715,8 +700,7 @@ IntToCString(ToCStringBuf *cbuf, jsint i, jsint base = 10)
|
||||
if (i < 0)
|
||||
*--cp = '-';
|
||||
|
||||
JS_ASSERT(cp >= cbuf->sbuf);
|
||||
return cp;
|
||||
return cp.get();
|
||||
}
|
||||
|
||||
static JSString * JS_FASTCALL
|
||||
@ -1282,23 +1266,14 @@ IndexToString(JSContext *cx, uint32 index)
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
/* +1, since MAX_LENGTH does not count the null char. */
|
||||
JS_STATIC_ASSERT(JSShortString::MAX_LENGTH + 1 >= sizeof("4294967295"));
|
||||
|
||||
jschar *storage = str->inlineStorageBeforeInit();
|
||||
size_t length = JSShortString::MAX_SHORT_LENGTH;
|
||||
const RangedPtr<jschar> end(storage + length, storage, length + 1);
|
||||
RangedPtr<jschar> cp = end;
|
||||
*cp = '\0';
|
||||
*end = '\0';
|
||||
|
||||
uint32 u = index;
|
||||
do {
|
||||
uint32 newu = u / 10, digit = u % 10;
|
||||
*--cp = '0' + digit;
|
||||
u = newu;
|
||||
} while (u > 0);
|
||||
RangedPtr<jschar> start = BackfillIndexInCharBuffer(index, end);
|
||||
|
||||
str->initAtOffsetInBuffer(cp.get(), end - cp);
|
||||
str->initAtOffsetInBuffer(start.get(), end - start);
|
||||
|
||||
c->dtoaCache.cache(10, index, str);
|
||||
return str;
|
||||
|
Loading…
x
Reference in New Issue
Block a user