Bug 810285 part 1 - Various jit-test fixes. r=djvj
authorJan de Mooij <jdemooij@mozilla.com>
Mon, 12 Nov 2012 13:15:41 +0100
changeset 112741 210ba1717fe0b2aa954776d06634d7957864ab58
parent 112740 281c54efd9918d37eb6121f751119141a7165cb5
child 112742 1e550841ca78200a08235259b41009efb2453ec9
push id1351
push userjandemooij@gmail.com
push dateMon, 12 Nov 2012 12:18:00 +0000
reviewersdjvj
bugs810285
milestone19.0a1
Bug 810285 part 1 - Various jit-test fixes. r=djvj
js/src/ion/BaselineJIT.cpp
js/src/ion/IonFrameIterator.h
js/src/ion/IonFrames.cpp
--- a/js/src/ion/BaselineJIT.cpp
+++ b/js/src/ion/BaselineJIT.cpp
@@ -4,16 +4,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "BaselineCompiler.h"
 #include "BaselineIC.h"
 #include "BaselineJIT.h"
 #include "CompileInfo.h"
+#include "IonSpewer.h"
 
 using namespace js;
 using namespace js::ion;
 
 BaselineScript::BaselineScript()
   : method_(NULL)
 { }
 
@@ -34,22 +35,54 @@ class AutoDestroyAllocator
 
     ~AutoDestroyAllocator()
     {
         if (alloc)
             js_delete(alloc);
     }
 };
 
+static bool
+CheckFrame(StackFrame *fp)
+{
+    if (fp->isConstructing()) {
+        IonSpew(IonSpew_Abort, "BASELINE FIXME: constructor frame!");
+        return false;
+    }
+
+    if (fp->isEvalFrame()) {
+        // Eval frames are not yet supported.
+        IonSpew(IonSpew_Abort, "BASELINE FIXME: eval frame!");
+        return false;
+    }
+
+    if (fp->isGeneratorFrame()) {
+        IonSpew(IonSpew_Abort, "generator frame");
+        return false;
+    }
+
+    if (fp->isDebuggerFrame()) {
+        IonSpew(IonSpew_Abort, "BASELINE FIXME: debugger frame!");
+        return false;
+    }
+
+    if (fp->annotation()) {
+        IonSpew(IonSpew_Abort, "frame is annotated");
+        return false;
+    }
+
+    return true;
+}
+
 static IonExecStatus
 EnterBaseline(JSContext *cx, StackFrame *fp, void *jitcode)
 {
     JS_CHECK_RECURSION(cx, return IonExec_Error);
     JS_ASSERT(ion::IsEnabled(cx));
-    //XXXJS_ASSERT(CheckFrame(fp));
+    JS_ASSERT(CheckFrame(fp));
 
     EnterIonCode enter = cx->compartment->ionCompartment()->enterJITInfallible();
 
     // maxArgc is the maximum of arguments between the number of actual
     // arguments and the number of formal arguments. It accounts for |this|.
     int maxArgc = 0;
     Value *maxArgv = NULL;
     int numActualArgs = 0;
@@ -117,46 +150,55 @@ ion::EnterBaselineMethod(JSContext *cx, 
     RootedScript script(cx, fp->script());
     BaselineScript *baseline = script->baseline;
     IonCode *code = baseline->method();
     void *jitcode = code->raw();
 
     return EnterBaseline(cx, fp, jitcode);
 }
 
-MethodStatus
-ion::CanEnterBaselineJIT(JSContext *cx, HandleScript script, StackFrame *fp)
+static MethodStatus
+BaselineCompile(JSContext *cx, HandleScript script, StackFrame *fp)
 {
-    if (script->baseline)
+    if (script->hasBaselineScript())
         return Method_Compiled;
 
-    if (!cx->compartment->ensureIonCompartmentExists(cx))
-        return Method_Error;
-
     LifoAlloc *alloc = cx->new_<LifoAlloc>(BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
     if (!alloc)
         return Method_Error;
 
     AutoDestroyAllocator autoDestroy(alloc);
 
     TempAllocator *temp = alloc->new_<TempAllocator>(alloc);
     if (!temp)
         return Method_Error;
 
     IonContext ictx(cx, cx->compartment, temp);
 
     BaselineCompiler compiler(cx, script);
     if (!compiler.init())
         return Method_Error;
 
-    MethodStatus status = compiler.compile();
+    return compiler.compile();
+}
+
+MethodStatus
+ion::CanEnterBaselineJIT(JSContext *cx, HandleScript script, StackFrame *fp)
+{
+    if (!CheckFrame(fp))
+        return Method_CantCompile;
+
+    if (!cx->compartment->ensureIonCompartmentExists(cx))
+        return Method_Error;
+
+    MethodStatus status = BaselineCompile(cx, script, fp);
     if (status != Method_Compiled)
         return status;
 
-    // This can GC, so afterward, script->ion is not guaranteed to be valid.
+    // This can GC, so afterward, script->baseline is not guaranteed to be valid.
     if (!cx->compartment->ionCompartment()->enterJIT(cx))
         return Method_Error;
 
     if (!script->baseline)
         return Method_Skipped;
 
     return Method_Compiled;
 }
--- a/js/src/ion/IonFrameIterator.h
+++ b/js/src/ion/IonFrameIterator.h
@@ -109,16 +109,22 @@ class IonFrameIterator
     // Returns whether the JS frame has been invalidated and, if so,
     // places the invalidated Ion script in |ionScript|.
     bool checkInvalidation(IonScript **ionScript) const;
     bool checkInvalidation() const;
 
     bool isScripted() const {
         return type_ == IonFrame_BaselineJS || type_ == IonFrame_OptimizedJS;
     }
+    bool isBaselineJS() const {
+        return type_ == IonFrame_BaselineJS;
+    }
+    bool isOptimizedJS() const {
+        return type_ == IonFrame_OptimizedJS;
+    }
     bool isNative() const;
     bool isOOLNativeGetter() const;
     bool isOOLPropertyOp() const;
     bool isDOMExit() const;
     bool isEntry() const {
         return type_ == IonFrame_Entry;
     }
     bool isFunctionFrame() const;
--- a/js/src/ion/IonFrames.cpp
+++ b/js/src/ion/IonFrames.cpp
@@ -308,17 +308,17 @@ ion::HandleException(ResumeFromException
     IonSpew(IonSpew_Invalidate, "handling exception");
 
     // Immediately remove any bailout frame guard that might be left over from
     // an error in between ConvertFrames and ThunkToInterpreter.
     js_delete(cx->runtime->ionActivation->maybeTakeBailout());
 
     IonFrameIterator iter(cx->runtime->ionTop);
     while (!iter.isEntry()) {
-        if (iter.isScripted()) {
+        if (iter.isOptimizedJS()) {
             // Search each inlined frame for live iterator objects, and close
             // them.
             InlineFrameIterator frames(&iter);
             for (;;) {
                 CloseLiveIterators(cx, frames);
 
                 // When profiling, each frame popped needs a notification that
                 // the function has exited, so invoke the probe that a function