Bug 1113139 - Don't attach stubs in NameIC if the lookup would throw. (r=shu)
authorEric Faust <efaustbmo@gmail.com>
Mon, 05 Jan 2015 14:26:57 -0800
changeset 247964 73eadfc19bba78adaba9cef4e9b38decce37b030
parent 247963 576c21be1808221944401b82b0c23e0565d03b98
child 247965 8ef1de3364d77bf56d49e2c25171292703843750
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu
bugs1113139
milestone37.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 1113139 - Don't attach stubs in NameIC if the lookup would throw. (r=shu)
js/src/jit-test/tests/ion/bug1113139.js
js/src/jit/IonCaches.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1113139.js
@@ -0,0 +1,9 @@
+var lfcode = new Array();
+lfcode.push = function(x) { eval("(function() { " + x + " })();"); };
+lfcode.push("\
+function error(str) { try { eval(str); } catch (e) { return e; } }\
+const YIELD_PAREN = error('(function*(){(for (y of (yield 1, 2)) y)})').message;\
+const GENEXP_YIELD = error('(function*(){(for (x of yield 1) x)})').message;\
+const GENERIC = error('(for)').message;\
+const eval = [];\
+");
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -4384,37 +4384,38 @@ NameIC::update(JSContext *cx, size_t cac
     cache.getScriptedLocation(&script, &pc);
 
     RootedObject obj(cx);
     RootedObject holder(cx);
     RootedShape shape(cx);
     if (!LookupName(cx, name, scopeChain, &obj, &holder, &shape))
         return false;
 
+    // Look first. Don't generate cache entries if the lookup fails.
+    if (cache.isTypeOf()) {
+        if (!FetchName<true>(cx, obj, holder, name, shape, vp))
+            return false;
+    } else {
+        if (!FetchName<false>(cx, obj, holder, name, shape, vp))
+            return false;
+    }
+
     if (cache.canAttachStub()) {
         if (IsCacheableNameReadSlot(scopeChain, obj, holder, shape, pc, cache.outputReg())) {
             if (!cache.attachReadSlot(cx, outerScript, ion, scopeChain, obj,
                                       holder.as<NativeObject>(), shape))
             {
                 return false;
             }
         } else if (IsCacheableNameCallGetter(scopeChain, obj, holder, shape)) {
             if (!cache.attachCallGetter(cx, outerScript, ion, scopeChain, obj, holder, shape, returnAddr))
                 return false;
         }
     }
 
-    if (cache.isTypeOf()) {
-        if (!FetchName<true>(cx, obj, holder, name, shape, vp))
-            return false;
-    } else {
-        if (!FetchName<false>(cx, obj, holder, name, shape, vp))
-            return false;
-    }
-
     // Monitor changes to cache entry.
     types::TypeScript::Monitor(cx, script, pc, vp);
 
     return true;
 }
 
 bool
 CallsiteCloneIC::attach(JSContext *cx, HandleScript outerScript, IonScript *ion,