зеркало из https://github.com/mozilla/gecko-dev.git
Bug 945512: IonMonkey: Make regexp only hoistable after analysis it is safe, r=sstangl
This commit is contained in:
Родитель
74b2d314db
Коммит
1508b14577
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче