Bug 720316 - Convert RegExp indexes into uint32_t. r=luke

--HG--
extra : rebase_source : bc166b8b951b7142b27f423fdbb6aba7e3087d97
This commit is contained in:
Jeff Walden 2012-01-19 17:15:24 -08:00
parent 1dd37c3dde
commit 6dbeb964f0
7 changed files with 69 additions and 32 deletions

View File

@ -1015,6 +1015,29 @@ EmitObjectOp(JSContext *cx, ObjectBox *objbox, JSOp op, BytecodeEmitter *bce)
return EmitIndexOp(cx, op, bce->objectList.index(objbox), bce);
}
static bool
EmitIndex32(JSContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
{
const size_t len = 1 + UINT32_INDEX_LEN;
ptrdiff_t offset = EmitCheck(cx, bce, len);
if (offset < 0)
return false;
jsbytecode *next = bce->next();
next[0] = jsbytecode(op);
SET_UINT32_INDEX(next, index);
bce->current->next = next + len;
UpdateDepth(cx, bce, offset);
CheckTypeSet(cx, bce, op);
return true;
}
static bool
EmitRegExp(JSContext *cx, uint32_t index, BytecodeEmitter *bce)
{
return EmitIndex32(cx, JSOP_REGEXP, index, bce);
}
/*
* What good are ARGNO_LEN and SLOTNO_LEN, you ask? The answer is that, apart
* from EmitSlotIndexOp, they abstract out the detail that both are 2, and in
@ -6670,7 +6693,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
case PNK_REGEXP:
JS_ASSERT(pn->isOp(JSOP_REGEXP));
ok = EmitIndexOp(cx, JSOP_REGEXP, bce->regexpList.index(pn->pn_objbox), bce);
ok = EmitRegExp(cx, bce->regexpList.index(pn->pn_objbox), bce);
break;
#if JS_HAS_XML_SUPPORT

View File

@ -1603,8 +1603,8 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
* Initialize the index segment register used by LOAD_ATOM and
* GET_FULL_INDEX macros below. As a register we use a pointer based on
* the atom map to turn frequently executed LOAD_ATOM into simple array
* access. For less frequent object and regexp loads we have to recover
* the segment from atoms pointer first.
* access. For less frequent object loads we have to recover the segment
* from atoms pointer first.
*/
JSAtom **atoms = script->atoms;
@ -3085,7 +3085,7 @@ BEGIN_CASE(JSOP_REGEXP)
* Push a regexp object cloned from the regexp literal object mapped by the
* bytecode at pc.
*/
jsatomid index = GET_FULL_INDEX(0);
uint32_t index = GET_UINT32_INDEX(regs.pc);
JSObject *proto = regs.fp()->scopeChain().global().getOrCreateRegExpPrototype(cx);
if (!proto)
goto error;

View File

@ -570,8 +570,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
}
case JOF_ATOM:
case JOF_OBJECT:
case JOF_REGEXP: {
case JOF_OBJECT: {
uintN index = js_GetIndexFromBytecode(script, pc, 0);
jsval v;
if (type == JOF_ATOM) {
@ -582,17 +581,15 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
v = STRING_TO_JSVAL(atom);
}
} else {
JSObject *obj;
if (type == JOF_OBJECT) {
/* Don't call obj.toSource if analysis/inference is active. */
if (cx->compartment->activeAnalysis) {
Sprint(sp, " object");
break;
}
obj = script->getObject(index);
} else {
obj = script->getRegExp(index);
JS_ASSERT(type == JOF_OBJECT);
/* Don't call obj.toSource if analysis/inference is active. */
if (cx->compartment->activeAnalysis) {
Sprint(sp, " object");
break;
}
JSObject *obj = script->getObject(index);
v = OBJECT_TO_JSVAL(obj);
}
{
@ -604,6 +601,15 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
break;
}
case JOF_REGEXP: {
JSObject *obj = script->getRegExp(GET_UINT32_INDEX(pc));
JSAutoByteString bytes;
if (!ToDisassemblySource(cx, ObjectValue(*obj), &bytes))
return 0;
Sprint(sp, " %s", bytes.ptr());
break;
}
case JOF_TABLESWITCH:
{
jsint i, low, high;
@ -2662,9 +2668,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
#define LOAD_FUNCTION(PCOFF) \
GET_FUNCTION_FROM_BYTECODE(jp->script, pc, PCOFF, fun)
#define LOAD_REGEXP(PCOFF) \
GET_REGEXP_FROM_BYTECODE(jp->script, pc, PCOFF, obj)
#define GET_SOURCE_NOTE_ATOM(sn, atom) \
JS_BEGIN_MACRO \
jsatomid atomIndex_ = (jsatomid) js_GetSrcNoteOffset((sn), 0); \
@ -4934,7 +4937,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
goto sprint_string;
case JSOP_REGEXP:
GET_REGEXP_FROM_BYTECODE(jp->script, pc, 0, obj);
obj = jp->script->getRegExp(GET_UINT32_INDEX(pc));
str = obj->asRegExp().toString(cx);
if (!str)
return NULL;

View File

@ -89,7 +89,7 @@ typedef enum JSOp {
#define JOF_INT32 14 /* int32_t immediate operand */
#define JOF_OBJECT 15 /* unsigned 16-bit object index */
#define JOF_SLOTOBJECT 16 /* uint16_t slot index + object index */
#define JOF_REGEXP 17 /* unsigned 16-bit regexp index */
#define JOF_REGEXP 17 /* unsigned 32-bit regexp index */
#define JOF_INT8 18 /* int8_t immediate operand */
#define JOF_ATOMOBJECT 19 /* uint16_t constant index + object index */
#define JOF_UINT16PAIR 20 /* pair of uint16_t immediates */
@ -191,10 +191,27 @@ SET_JUMP_OFFSET(jsbytecode *pc, int32_t off)
pc[4] = (jsbytecode)off;
}
#define UINT32_INDEX_LEN 4
static JS_ALWAYS_INLINE uint32_t
GET_UINT32_INDEX(jsbytecode *pc)
{
return (pc[1] << 24) | (pc[2] << 16) | (pc[3] << 8) | pc[4];
}
static JS_ALWAYS_INLINE void
SET_UINT32_INDEX(jsbytecode *pc, uint32_t index)
{
pc[1] = (jsbytecode)(index >> 24);
pc[2] = (jsbytecode)(index >> 16);
pc[3] = (jsbytecode)(index >> 8);
pc[4] = (jsbytecode)index;
}
/*
* A literal is indexed by a per-script atom or object maps. Most scripts
* have relatively few literals, so the standard JOF_ATOM, JOF_OBJECT and
* JOF_REGEXP formats specifies a fixed 16 bits of immediate operand index.
* have relatively few literals, so the standard JOF_ATOM and JOF_OBJECT
* format specifies a fixed 16 bits of immediate operand index.
* A script with more than 64K literals must wrap the bytecode into
* JSOP_INDEXBASE and JSOP_RESETBASE pair.
*/
@ -357,12 +374,6 @@ js_GetIndexFromBytecode(JSScript *script, jsbytecode *pc, ptrdiff_t pcoff);
fun = (script)->getFunction(index_); \
JS_END_MACRO
#define GET_REGEXP_FROM_BYTECODE(script, pc, pcoff, obj) \
JS_BEGIN_MACRO \
uintN index_ = js_GetIndexFromBytecode((script), (pc), (pcoff)); \
obj = (script)->getRegExp(index_); \
JS_END_MACRO
#ifdef __cplusplus
namespace js {

View File

@ -411,7 +411,7 @@ OPDEF(JSOP_GNAMEINC, 158,"gnameinc", NULL, 4, 0, 1, 15, JOF_ATOM|
OPDEF(JSOP_GNAMEDEC, 159,"gnamedec", NULL, 4, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3|JOF_GNAME|JOF_DECOMPOSE)
/* Regular expression literal requiring special "fork on exec" handling. */
OPDEF(JSOP_REGEXP, 160,"regexp", NULL, 3, 0, 1, 19, JOF_REGEXP)
OPDEF(JSOP_REGEXP, 160,"regexp", NULL, 5, 0, 1, 19, JOF_REGEXP)
/* XML (ECMA-357, a.k.a. "E4X") support. */
OPDEF(JSOP_DEFXMLNS, 161,"defxmlns", NULL, 1, 1, 0, 0, JOF_BYTE)

View File

@ -226,7 +226,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32_t id);
* and saved versions. If deserialization fails, the data should be
* invalidated if possible.
*/
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 104)
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 105)
/*
* Library-private functions.

View File

@ -6870,7 +6870,7 @@ mjit::Compiler::jsop_newinit()
bool
mjit::Compiler::jsop_regexp()
{
JSObject *obj = script->getRegExp(fullAtomIndex(PC));
JSObject *obj = script->getRegExp(GET_UINT32_INDEX(PC));
RegExpStatics *res = globalObj ? globalObj->getRegExpStatics() : NULL;
if (!globalObj ||