From 16da6f74c72a5032047a102a6f97f8d6b199315a Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Fri, 2 May 2014 13:04:12 -0700 Subject: [PATCH] Bug 1004527 - Don't eliminate MNewDerivedTypedObject from resume points and recover them on bailout. (r=nmatsakis) --- .../jit-test/tests/TypedObject/bug1004527.js | 8 +++++ js/src/jit/IonAnalysis.cpp | 10 ++++++- js/src/jit/MIR.h | 5 ++++ js/src/jit/Recover.cpp | 29 +++++++++++++++++++ js/src/jit/Recover.h | 15 +++++++++- 5 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 js/src/jit-test/tests/TypedObject/bug1004527.js diff --git a/js/src/jit-test/tests/TypedObject/bug1004527.js b/js/src/jit-test/tests/TypedObject/bug1004527.js new file mode 100644 index 000000000000..934b528bb0b1 --- /dev/null +++ b/js/src/jit-test/tests/TypedObject/bug1004527.js @@ -0,0 +1,8 @@ +if (!this.hasOwnProperty("TypedObject")) + quit(); + +var { ArrayType, StructType, uint32 } = TypedObject; +var L = 1024; +var Matrix = uint32.array(L, 2); +var matrix = new Matrix(); +evaluate("for (var i = 0; i < L; i++) matrix[i][0] = (function d() {});", { compileAndGo : true }); diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index b9804a63b111..02b4e69675f3 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -54,7 +54,7 @@ jit::SplitCriticalEdges(MIRGraph &graph) } // Operands to a resume point which are dead at the point of the resume can be -// replaced with undefined values. This analysis supports limited detection of +// replaced with a magic value. This analysis supports limited detection of // dead operands, pruning those which are defined in the resume point's basic // block and have no uses outside the block or at points later than the resume // point. @@ -93,6 +93,14 @@ jit::EliminateDeadResumePointOperands(MIRGenerator *mir, MIRGraph &graph) if (ins->isUnbox() || ins->isParameter() || ins->isTypeBarrier() || ins->isComputeThis()) continue; + // TypedObject intermediate values captured by resume points may + // be legitimately dead in Ion code, but are still needed if we + // bail out. They can recover on bailout. + if (ins->isNewDerivedTypedObject()) { + MOZ_ASSERT(ins->canRecoverOnBailout()); + continue; + } + // If the instruction's behavior has been constant folded into a // separate instruction, we can't determine precisely where the // instruction becomes dead and can't eliminate its uses. diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 72b91d897f36..a8425faf5152 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -1589,6 +1589,11 @@ class MNewDerivedTypedObject virtual AliasSet getAliasSet() const { return AliasSet::None(); } + + bool writeRecoverData(CompactBufferWriter &writer) const; + bool canRecoverOnBailout() const { + return true; + } }; // Abort parallel execution. diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp index 0a5c0bbcfc12..8f27a71ee4a0 100644 --- a/js/src/jit/Recover.cpp +++ b/js/src/jit/Recover.cpp @@ -9,6 +9,8 @@ #include "jscntxt.h" #include "jsmath.h" +#include "builtin/TypedObject.h" + #include "jit/IonSpewer.h" #include "jit/JitFrameIterator.h" #include "jit/MIR.h" @@ -167,3 +169,30 @@ RAdd::recover(JSContext *cx, SnapshotIterator &iter) const iter.storeInstructionResult(result); return true; } + +bool +MNewDerivedTypedObject::writeRecoverData(CompactBufferWriter &writer) const +{ + MOZ_ASSERT(canRecoverOnBailout()); + writer.writeUnsigned(uint32_t(RInstruction::Recover_NewDerivedTypedObject)); + return true; +} + +RNewDerivedTypedObject::RNewDerivedTypedObject(CompactBufferReader &reader) +{ } + +bool +RNewDerivedTypedObject::recover(JSContext *cx, SnapshotIterator &iter) const +{ + Rooted descr(cx, &iter.read().toObject().as()); + Rooted owner(cx, &iter.read().toObject().as()); + int32_t offset = iter.read().toInt32(); + + JSObject *obj = TypedObject::createDerived(cx, descr, owner, offset); + if (!obj) + return false; + + RootedValue result(cx, ObjectValue(*obj)); + iter.storeInstructionResult(result); + return true; +} diff --git a/js/src/jit/Recover.h b/js/src/jit/Recover.h index 135e1b701887..f3a037b68076 100644 --- a/js/src/jit/Recover.h +++ b/js/src/jit/Recover.h @@ -18,7 +18,8 @@ namespace jit { #define RECOVER_OPCODE_LIST(_) \ _(ResumePoint) \ - _(Add) + _(Add) \ + _(NewDerivedTypedObject) class RResumePoint; class SnapshotIterator; @@ -101,6 +102,18 @@ class RAdd MOZ_FINAL : public RInstruction bool recover(JSContext *cx, SnapshotIterator &iter) const; }; +class RNewDerivedTypedObject MOZ_FINAL : public RInstruction +{ + public: + RINSTRUCTION_HEADER_(NewDerivedTypedObject) + + virtual uint32_t numOperands() const { + return 3; + } + + bool recover(JSContext *cx, SnapshotIterator &iter) const; +}; + #undef RINSTRUCTION_HEADER_ const RResumePoint *