Bug 1133630 - handle stack overflows during analysis. r=jandem
authorLars T Hansen <lhansen@mozilla.com>
Thu, 15 Oct 2015 15:14:00 +0200
changeset 301318 e7ec2e6fccc46795066315a6ce94920d63fe9890
parent 301317 c5f4be1ae066ddb10865c6e95b63a8a01c09960c
child 301319 e940ae9e0f7121e4b5dbba6f30db812d2e97b4ee
push id5392
push userraliiev@mozilla.com
push dateMon, 14 Dec 2015 20:08:23 +0000
treeherdermozilla-beta@16ce8562a975 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1133630
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1133630 - handle stack overflows during analysis. r=jandem
js/src/jit/Ion.cpp
js/src/jit/IonAnalysis.cpp
js/src/jit/IonBuilder.h
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -2200,16 +2200,21 @@ IonCompile(JSContext* cx, JSScript* scri
         if (builder->hadActionableAbort()) {
             JSScript* abortScript;
             jsbytecode* abortPc;
             const char* abortMessage;
             builder->actionableAbortLocationAndMessage(&abortScript, &abortPc, &abortMessage);
             TrackIonAbort(cx, abortScript, abortPc, abortMessage);
         }
 
+        if (cx->isThrowingOverRecursed()) {
+            // Non-analysis compilations should never fail with stack overflow.
+            MOZ_CRASH("Stack overflow during compilation");
+        }
+
         return reason;
     }
 
     // If possible, compile the script off thread.
     if (options.offThreadCompilationAvailable()) {
         JitSpew(JitSpew_IonSyncLogs, "Can't log script %s:%" PRIuSIZE
                 ". (Compiled on background thread.)",
                 builderScript->filename(), builderScript->lineno());
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -3307,18 +3307,19 @@ jit::AnalyzeNewScriptDefiniteProperties(
 
     BaselineInspector inspector(script);
     const JitCompileOptions options(cx);
 
     IonBuilder builder(cx, CompileCompartment::get(cx->compartment()), options, &temp, &graph, constraints,
                        &inspector, &info, optimizationInfo, /* baselineFrame = */ nullptr);
 
     if (!builder.build()) {
-        if (builder.abortReason() == AbortReason_Alloc)
+        if (cx->isThrowingOverRecursed() || builder.abortReason() == AbortReason_Alloc)
             return false;
+        MOZ_ASSERT(!cx->isExceptionPending());
         return true;
     }
 
     FinishDefinitePropertiesAnalysis(cx, constraints);
 
     if (!SplitCriticalEdges(graph))
         return false;
 
@@ -3527,18 +3528,19 @@ jit::AnalyzeArgumentsUsage(JSContext* cx
 
     BaselineInspector inspector(script);
     const JitCompileOptions options(cx);
 
     IonBuilder builder(nullptr, CompileCompartment::get(cx->compartment()), options, &temp, &graph, constraints,
                        &inspector, &info, optimizationInfo, /* baselineFrame = */ nullptr);
 
     if (!builder.build()) {
-        if (builder.abortReason() == AbortReason_Alloc)
+        if (cx->isThrowingOverRecursed() || builder.abortReason() == AbortReason_Alloc)
             return false;
+        MOZ_ASSERT(!cx->isExceptionPending());
         return true;
     }
 
     if (!SplitCriticalEdges(graph))
         return false;
 
     if (!RenumberBlocks(graph))
         return false;
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -210,16 +210,19 @@ class IonBuilder
   public:
     IonBuilder(JSContext* analysisContext, CompileCompartment* comp,
                const JitCompileOptions& options, TempAllocator* temp,
                MIRGraph* graph, CompilerConstraintList* constraints,
                BaselineInspector* inspector, CompileInfo* info,
                const OptimizationInfo* optimizationInfo, BaselineFrameInspector* baselineFrame,
                size_t inliningDepth = 0, uint32_t loopDepth = 0);
 
+    // Callers of build() and buildInline() should always check whether the
+    // call overrecursed, if false is returned.  Overrecursion is not
+    // signaled as OOM and will not in general be caught by OOM paths.
     bool build();
     bool buildInline(IonBuilder* callerBuilder, MResumePoint* callerResumePoint,
                      CallInfo& callInfo);
 
   private:
     bool traverseBytecode();
     ControlStatus snoopControlFlow(JSOp op);
     bool processIterators();