Bug 1147371 - Always decompile argument names in self-hosted code in the caller frame. (r=arai)
authorShu-yu Guo <shu@rfrn.org>
Sat, 14 Jan 2017 14:51:39 -0800
changeset 374496 142dbb4bffc04efdb358df11293079d00af693fc
parent 374495 0b9c4069ed0f9ddf163a52b52abfd32bfffefcaa
child 374497 0d7224996287e80d2fb78ba163fd97d006a83ee4
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1147371
milestone53.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 1147371 - Always decompile argument names in self-hosted code in the caller frame. (r=arai)
js/src/jsopcode.cpp
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -87,17 +87,18 @@ static const char * const CodeToken[] = 
 const char * const js::CodeName[] = {
 #define OPNAME(op, val, name, ...)  name,
     FOR_EACH_OPCODE(OPNAME)
 #undef OPNAME
 };
 
 /************************************************************************/
 
-#define COUNTS_LEN 16
+static bool
+DecompileArgumentFromStack(JSContext* cx, int formalIndex, char** res);
 
 size_t
 js::GetVariableBytecodeLength(jsbytecode* pc)
 {
     JSOp op = JSOp(*pc);
     MOZ_ASSERT(CodeSpec[op].length == -1);
     switch (op) {
       case JSOP_TABLESWITCH: {
@@ -1253,16 +1254,34 @@ ExpressionDecompiler::decompilePC(jsbyte
 
     switch (op) {
       case JSOP_GETGNAME:
       case JSOP_GETNAME:
       case JSOP_GETINTRINSIC:
         return write(loadAtom(pc));
       case JSOP_GETARG: {
         unsigned slot = GET_ARGNO(pc);
+
+        // For self-hosted scripts that are called from non-self-hosted code,
+        // decompiling the parameter name in the self-hosted script is
+        // unhelpful. Decompile the argument name instead.
+        if (script->selfHosted()) {
+            char* result;
+            if (!DecompileArgumentFromStack(cx, slot, &result))
+                return false;
+
+            // Note that decompiling the argument in the parent frame might
+            // not succeed.
+            if (result) {
+		bool ok = write(result);
+                js_free(result);
+		return ok;
+            }
+        }
+
         JSAtom* atom = getArg(slot);
         if (!atom)
             return false;
         return write(atom);
       }
       case JSOP_GETLOCAL: {
         JSAtom* atom = FrameSlotName(script, pc);
         MOZ_ASSERT(atom);
@@ -1593,22 +1612,27 @@ DecompileArgumentFromStack(JSContext* cx
      * Settle on the nearest script frame, which should be the builtin that
      * called the intrinsic.
      */
     FrameIter frameIter(cx);
     MOZ_ASSERT(!frameIter.done());
     MOZ_ASSERT(frameIter.script()->selfHosted());
 
     /*
-     * Get the second-to-top frame, the caller of the builtin that called the
-     * intrinsic.
+     * Get the second-to-top frame, the non-self-hosted caller of the builtin
+     * that called the intrinsic.
      */
     ++frameIter;
-    if (frameIter.done() || !frameIter.hasScript() || frameIter.compartment() != cx->compartment())
+    if (frameIter.done() ||
+        !frameIter.hasScript() ||
+        frameIter.script()->selfHosted() ||
+        frameIter.compartment() != cx->compartment())
+    {
         return true;
+    }
 
     RootedScript script(cx, frameIter.script());
     jsbytecode* current = frameIter.pc();
 
     MOZ_ASSERT(script->containsPC(current));
 
     if (current < script->main())
         return true;