Bug 788096 - Undo part 1 (c77231ed11be) because it regressed Talos Trace Malloc Allocs by ~1%. r=me.

--HG--
extra : rebase_source : 2422ef3314448f0ce7e3ee80b566d75293844e2f
This commit is contained in:
Nicholas Nethercote 2012-09-05 23:03:31 -07:00
parent efa676d26e
commit 7df7fbc4ed
6 changed files with 42 additions and 37 deletions

View File

@ -152,8 +152,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
ObjectBox *funbox = parser.newObjectBox(callerFrame->fun());
if (!funbox)
return NULL;
if (!bce.objectList.append(funbox))
return NULL;
bce.objectList.add(funbox);
}
}

View File

@ -114,8 +114,6 @@ BytecodeEmitter::BytecodeEmitter(BytecodeEmitter *parent, Parser *parser, Shared
arrayCompDepth(0),
emitLevel(0),
constList(sc->context),
objectList(sc->context),
regexpList(sc->context),
typesetCount(0),
hasSingletons(false),
emittingForInit(false),
@ -822,11 +820,7 @@ static bool
EmitObjectOp(JSContext *cx, ObjectBox *objbox, JSOp op, BytecodeEmitter *bce)
{
JS_ASSERT(JOF_OPTYPE(op) == JOF_OBJECT);
if (!bce->objectList.append(objbox))
return false;
return EmitIndex32(cx, op, bce->objectList.length() - 1, bce);
return EmitIndex32(cx, op, bce->objectList.add(objbox), bce);
}
static bool
@ -4884,10 +4878,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
}
/* Make the function object a literal in the outer script's pool. */
if (!bce->objectList.append(pn->pn_funbox))
return false;
unsigned index = bce->objectList.length() - 1;
unsigned index = bce->objectList.add(pn->pn_funbox);
/* Non-hoisted functions simply emit their respective op. */
if (!pn->functionIsHoisted()) {
@ -5832,11 +5823,10 @@ EmitObject(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
ObjectBox *objbox = bce->parser->newObjectBox(obj);
if (!objbox)
return false;
if (!bce->objectList.append(objbox))
return false;
unsigned index = bce->objectList.add(objbox);
MOZ_STATIC_ASSERT(JSOP_NEWINIT_LENGTH == JSOP_NEWOBJECT_LENGTH,
"newinit and newobject must have equal length to edit in-place");
EMIT_UINT32_IN_PLACE(offset, JSOP_NEWOBJECT, uint32_t(bce->objectList.length() - 1));
EMIT_UINT32_IN_PLACE(offset, JSOP_NEWOBJECT, uint32_t(index));
}
return true;
@ -6532,9 +6522,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
case PNK_REGEXP:
JS_ASSERT(pn->isOp(JSOP_REGEXP));
if (!bce->regexpList.append(pn->pn_objbox))
return false;
ok = EmitRegExp(cx, bce->regexpList.length() - 1, bce);
ok = EmitRegExp(cx, bce->regexpList.add(pn->pn_objbox), bce);
break;
#if JS_HAS_XML_SUPPORT
@ -7023,24 +7011,39 @@ CGTryNoteList::finish(TryNoteArray *array)
* for global regexps) and on any ad-hoc properties. Also, __proto__ refers to
* the pre-compilation prototype, a pigeon-hole problem for instanceof tests.
*/
unsigned
CGObjectList::add(ObjectBox *objbox)
{
JS_ASSERT(!objbox->emitLink);
objbox->emitLink = lastbox;
lastbox = objbox;
return length++;
}
unsigned
CGObjectList::indexOf(JSObject *obj)
{
for (unsigned i = 0; i < length(); i++)
if (list[i]->object == obj)
return i;
JS_NOT_REACHED("couldn't find index for object");
JS_ASSERT(length > 0);
unsigned index = length - 1;
for (ObjectBox *box = lastbox; box->object != obj; box = box->emitLink)
index--;
return index;
}
void
CGObjectList::finish(ObjectArray *array)
{
JS_ASSERT(length() <= INDEX_LIMIT);
JS_ASSERT(length() == array->length);
JS_ASSERT(length <= INDEX_LIMIT);
JS_ASSERT(length == array->length);
for (unsigned i = 0; i < length(); i++)
array->vector[i] = list[i]->object;
js::HeapPtrObject *cursor = array->vector + array->length;
ObjectBox *objbox = lastbox;
do {
--cursor;
JS_ASSERT(!*cursor);
*cursor = objbox->object;
} while ((objbox = objbox->emitLink) != NULL);
JS_ASSERT(cursor == array->vector);
}
void

View File

@ -37,12 +37,13 @@ struct CGTryNoteList {
};
struct CGObjectList {
Vector<ObjectBox*> list;
CGObjectList(JSContext *cx) : list(cx) {}
uint32_t length; /* number of emitted so far objects */
ObjectBox *lastbox; /* last emitted object */
bool append(ObjectBox *objbox) { return list.append(objbox); }
CGObjectList() : length(0), lastbox(NULL) {}
unsigned add(ObjectBox *objbox);
unsigned indexOf(JSObject *obj);
size_t length() const { return list.length(); }
void finish(ObjectArray *array);
};

View File

@ -1428,6 +1428,7 @@ LinkUseToDef(ParseNode *pn, Definition *dn)
struct ObjectBox {
ObjectBox *traceLink;
ObjectBox *emitLink;
JSObject *object;
bool isFunctionBox;

View File

@ -357,6 +357,7 @@ Parser::~Parser()
ObjectBox::ObjectBox(ObjectBox* traceLink, JSObject *obj)
: traceLink(traceLink),
emitLink(NULL),
object(obj),
isFunctionBox(false)
{

View File

@ -1616,15 +1616,15 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
{
/* The counts of indexed things must be checked during code generation. */
JS_ASSERT(bce->atomIndices->count() <= INDEX_LIMIT);
JS_ASSERT(bce->objectList.length() <= INDEX_LIMIT);
JS_ASSERT(bce->regexpList.length() <= INDEX_LIMIT);
JS_ASSERT(bce->objectList.length <= INDEX_LIMIT);
JS_ASSERT(bce->regexpList.length <= INDEX_LIMIT);
uint32_t mainLength = bce->offset();
uint32_t prologLength = bce->prologOffset();
uint32_t nsrcnotes = uint32_t(bce->countFinalSourceNotes());
if (!partiallyInit(cx, script, prologLength + mainLength, nsrcnotes, bce->atomIndices->count(),
bce->objectList.length(), bce->regexpList.length(),
bce->tryNoteList.length(), bce->constList.length(), bce->typesetCount))
bce->objectList.length, bce->regexpList.length, bce->tryNoteList.length(),
bce->constList.length(), bce->typesetCount))
return false;
JS_ASSERT(script->mainOffset == 0);
@ -1653,9 +1653,9 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
return false;
if (bce->tryNoteList.length() != 0)
bce->tryNoteList.finish(script->trynotes());
if (bce->objectList.length() != 0)
if (bce->objectList.length != 0)
bce->objectList.finish(script->objects());
if (bce->regexpList.length() != 0)
if (bce->regexpList.length != 0)
bce->regexpList.finish(script->regexps());
if (bce->constList.length() != 0)
bce->constList.finish(script->consts());