Bug 667824 - Make tracer match changes to JSOP_CALL (r=waldo)
authorLuke Wagner <luke@mozilla.com>
Thu, 30 Jun 2011 09:23:15 -0700
changeset 72360 c1afc79e767612212f89e23455b2fd7ca30c8943
parent 72359 38322c7498ff46cfeed002028b7ff18618e89b52
child 72361 f59568ec0513a083130f0bec33041b7b64c543fb
push idunknown
push userunknown
push dateunknown
reviewerswaldo
bugs667824
milestone7.0a1
Bug 667824 - Make tracer match changes to JSOP_CALL (r=waldo)
js/src/jit-test/tests/basic/testCallFunctionPrototypeInALoop.js
js/src/jsinterp.cpp
js/src/jstracer.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testCallFunctionPrototypeInALoop.js
@@ -0,0 +1,4 @@
+var x;
+for (var a = 0; a < 8; a++) {
+    Function.prototype()
+}
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -4072,16 +4072,18 @@ BEGIN_CASE(JSOP_FUNAPPLY)
 {
     CallArgs args = CallArgsFromSp(GET_ARGC(regs.pc), regs.sp);
     JS_ASSERT(args.base() >= regs.fp()->base());
 
     MaybeConstruct construct = *regs.pc == JSOP_NEW ? CONSTRUCT : NO_CONSTRUCT;
 
     JSObject *callee;
     JSFunction *fun;
+
+    /* Don't bother trying to fast-path calls to scripted non-constructors. */
     if (!IsFunctionObject(args.calleev(), &callee, &fun) || !fun->isInterpretedConstructor()) {
         if (construct) {
             if (!InvokeConstructor(cx, args))
                 goto error;
         } else {
             if (!Invoke(cx, args))
                 goto error;
         }
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -13742,16 +13742,20 @@ TraceRecorder::createThis(JSObject& ctor
 }
 
 JS_REQUIRES_STACK RecordingStatus
 TraceRecorder::interpretedFunctionCall(Value& fval, JSFunction* fun, uintN argc, bool constructing)
 {
     if (fval.toObject().getGlobal() != globalObj)
         RETURN_STOP("JSOP_CALL or JSOP_NEW crosses global scopes");
 
+    JS_ASSERT(fun->isInterpreted());
+    if (!fun->isInterpretedConstructor())
+        RETURN_STOP("Non-interpreted constructors get called via Invoke");
+
     StackFrame* const fp = cx->fp();
 
     if (constructing) {
         LIns* thisobj_ins;
         CHECK_STATUS(createThis(fval.toObject(), get(&fval), &thisobj_ins));
         stack(-int(argc) - 1, thisobj_ins);
     }