Bug 1063488 - Treat MaybeCopyElementsForWrite as possibly overwriting an object's elements pointer, r=jandem.

This commit is contained in:
Brian Hackett 2014-09-11 09:07:20 -06:00
parent cab101a3ef
commit 6112a6a45c
3 changed files with 31 additions and 9 deletions

View File

@ -0,0 +1,16 @@
function foo(a, b) {
var x = b[0];
for (var i = 0; i < 5; i++) {
a[i + 1] = 0;
x += b[i];
}
assertEq(x, 2);
}
function bar() {
for (var i = 0; i < 5; i++) {
var arr = [1,2,3,4,5,6];
foo(arr, arr);
}
}
bar();

View File

@ -745,6 +745,12 @@ class MDefinition : public MNode
bool isEffectful() const {
return getAliasSet().isStore();
}
#ifdef DEBUG
virtual bool needsResumePoint() const {
// Return whether this instruction should have its own resume point.
return isEffectful();
}
#endif
virtual bool mightAlias(const MDefinition *store) const {
// Return whether this load may depend on the specified store, given
// that the alias sets intersect. This may be refined to exclude
@ -6829,15 +6835,15 @@ class MMaybeCopyElementsForWrite
return congruentIfOperandsEqual(ins);
}
AliasSet getAliasSet() const {
// This instruction can read and write to the elements' contents,
// in the same manner as MConvertElementsToDoubles. As with that
// instruction, this is safe to consolidate and freely reorder this
// instruction, though this must precede any loads of the object's
// elements pointer or writes to the object's elements. The latter
// property is ensured by chaining this with the object definition
// itself, in the same manner as MBoundsCheck.
return AliasSet::None();
return AliasSet::Store(AliasSet::ObjectFields);
}
#ifdef DEBUG
bool needsResumePoint() const {
// This instruction is idempotent and does not change observable
// behavior, so does not need its own resume point.
return false;
}
#endif
TypePolicy *typePolicy() {
return this;

View File

@ -995,7 +995,7 @@ CodeGeneratorShared::callVM(const VMFunction &fun, LInstruction *ins, const Regi
if (ins->mirRaw()) {
JS_ASSERT(ins->mirRaw()->isInstruction());
MInstruction *mir = ins->mirRaw()->toInstruction();
JS_ASSERT_IF(mir->isEffectful(), mir->resumePoint());
JS_ASSERT_IF(mir->needsResumePoint(), mir->resumePoint());
}
#endif