Bug 945512: IonMonkey: Make regexp only hoistable after analysis it is safe, r=sstangl

This commit is contained in:
Hannes Verschore 2014-04-09 13:16:20 +02:00
Родитель 74b2d314db
Коммит 1508b14577
5 изменённых файлов: 77 добавлений и 15 удалений

Просмотреть файл

@ -0,0 +1,12 @@
var handler = {
has: function (name) {
assertEq(1, 2);
}
};
for (var i=0; i<10; i++) {
var regex = /undefined/;
regex.__proto__ = Proxy.createFunction(handler, function(){})
}

Просмотреть файл

@ -1256,6 +1256,11 @@ OptimizeMIR(MIRGenerator *mir)
{
MIRGraph &graph = mir->graph();
if (!mir->compilingAsmJS()) {
if (!MakeMRegExpHoistable(graph))
return false;
}
IonSpewPass("BuildSSA");
AssertBasicGraphCoherency(graph);

Просмотреть файл

@ -1009,6 +1009,63 @@ jit::ApplyTypeInformation(MIRGenerator *mir, MIRGraph &graph)
return true;
}
bool
jit::MakeMRegExpHoistable(MIRGraph &graph)
{
for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); block++) {
for (MDefinitionIterator iter(*block); iter; iter++) {
if (!iter->isRegExp())
continue;
MRegExp *regexp = iter->toRegExp();
// Test if MRegExp is hoistable by looking at all uses.
bool hoistable = true;
for (MUseIterator i = regexp->usesBegin(); i != regexp->usesEnd(); i++) {
// Ignore resume points. At this point all uses are listed.
// No DCE or GVN or something has happened.
if (i->consumer()->isResumePoint())
continue;
JS_ASSERT(i->consumer()->isDefinition());
// All MRegExp* MIR's don't adjust the regexp.
MDefinition *use = i->consumer()->toDefinition();
if (use->isRegExpReplace())
continue;
if (use->isRegExpExec())
continue;
if (use->isRegExpTest())
continue;
hoistable = false;
break;
}
if (!hoistable)
continue;
// Make MRegExp hoistable
regexp->setMovable();
// That would be incorrect for global/sticky, because lastIndex could be wrong.
// Therefore setting the lastIndex to 0. That is faster than a not movable regexp.
RegExpObject *source = regexp->source();
if (source->sticky() || source->global()) {
JS_ASSERT(regexp->mustClone());
MConstant *zero = MConstant::New(graph.alloc(), Int32Value(0));
regexp->block()->insertAfter(regexp, zero);
MStoreFixedSlot *lastIndex =
MStoreFixedSlot::New(graph.alloc(), regexp, RegExpObject::lastIndexSlot(), zero);
regexp->block()->insertAfter(zero, lastIndex);
}
}
}
return true;
}
bool
jit::RenumberBlocks(MIRGraph &graph)
{

Просмотреть файл

@ -38,6 +38,9 @@ EliminateDeadCode(MIRGenerator *mir, MIRGraph &graph);
bool
ApplyTypeInformation(MIRGenerator *mir, MIRGraph &graph);
bool
MakeMRegExpHoistable(MIRGraph &graph);
bool
RenumberBlocks(MIRGraph &graph);

Просмотреть файл

@ -9399,21 +9399,6 @@ IonBuilder::jsop_regexp(RegExpObject *reobj)
current->add(regexp);
current->push(regexp);
regexp->setMovable();
// The MRegExp is set to be movable.
// That would be incorrect for global/sticky, because lastIndex could be wrong.
// Therefore setting the lastIndex to 0. That is faster than removing the movable flag.
if (reobj->sticky() || reobj->global()) {
JS_ASSERT(mustClone);
MConstant *zero = MConstant::New(alloc(), Int32Value(0));
current->add(zero);
MStoreFixedSlot *lastIndex =
MStoreFixedSlot::New(alloc(), regexp, RegExpObject::lastIndexSlot(), zero);
current->add(lastIndex);
}
return true;
}