js/src/jit/Recover.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "jit/Recover.h"
     9 #include "jit/IonSpewer.h"
    10 #include "jit/MIR.h"
    11 #include "jit/MIRGraph.h"
    13 using namespace js;
    14 using namespace js::jit;
    16 void
    17 RInstruction::readRecoverData(CompactBufferReader &reader, RInstructionStorage *raw)
    18 {
    19     uint32_t op = reader.readUnsigned();
    20     switch (Opcode(op)) {
    21       case Recover_ResumePoint:
    22         new (raw->addr()) RResumePoint(reader);
    23         break;
    24       default:
    25         MOZ_ASSUME_UNREACHABLE("Bad decoding of the previous instruction?");
    26         break;
    27     }
    28 }
    30 bool
    31 MResumePoint::writeRecoverData(CompactBufferWriter &writer) const
    32 {
    33     writer.writeUnsigned(uint32_t(RInstruction::Recover_ResumePoint));
    35     MBasicBlock *bb = block();
    36     JSFunction *fun = bb->info().funMaybeLazy();
    37     JSScript *script = bb->info().script();
    38     uint32_t exprStack = stackDepth() - bb->info().ninvoke();
    40 #ifdef DEBUG
    41     // Ensure that all snapshot which are encoded can safely be used for
    42     // bailouts.
    43     if (GetIonContext()->cx) {
    44         uint32_t stackDepth;
    45         bool reachablePC;
    46         jsbytecode *bailPC = pc();
    48         if (mode() == MResumePoint::ResumeAfter)
    49             bailPC = GetNextPc(pc());
    51         if (!ReconstructStackDepth(GetIonContext()->cx, script,
    52                                    bailPC, &stackDepth, &reachablePC))
    53         {
    54             return false;
    55         }
    57         if (reachablePC) {
    58             if (JSOp(*bailPC) == JSOP_FUNCALL) {
    59                 // For fun.call(this, ...); the reconstructStackDepth will
    60                 // include the this. When inlining that is not included.  So the
    61                 // exprStackSlots will be one less.
    62                 MOZ_ASSERT(stackDepth - exprStack <= 1);
    63             } else if (JSOp(*bailPC) != JSOP_FUNAPPLY &&
    64                        !IsGetPropPC(bailPC) && !IsSetPropPC(bailPC))
    65             {
    66                 // For fun.apply({}, arguments) the reconstructStackDepth will
    67                 // have stackdepth 4, but it could be that we inlined the
    68                 // funapply. In that case exprStackSlots, will have the real
    69                 // arguments in the slots and not be 4.
    71                 // With accessors, we have different stack depths depending on
    72                 // whether or not we inlined the accessor, as the inlined stack
    73                 // contains a callee function that should never have been there
    74                 // and we might just be capturing an uneventful property site,
    75                 // in which case there won't have been any violence.
    76                 MOZ_ASSERT(exprStack == stackDepth);
    77             }
    78         }
    79     }
    80 #endif
    82     // Test if we honor the maximum of arguments at all times.  This is a sanity
    83     // check and not an algorithm limit. So check might be a bit too loose.  +4
    84     // to account for scope chain, return value, this value and maybe
    85     // arguments_object.
    86     MOZ_ASSERT(CountArgSlots(script, fun) < SNAPSHOT_MAX_NARGS + 4);
    88     uint32_t implicit = StartArgSlot(script);
    89     uint32_t formalArgs = CountArgSlots(script, fun);
    90     uint32_t nallocs = formalArgs + script->nfixed() + exprStack;
    92     IonSpew(IonSpew_Snapshots, "Starting frame; implicit %u, formals %u, fixed %u, exprs %u",
    93             implicit, formalArgs - implicit, script->nfixed(), exprStack);
    95     uint32_t pcoff = script->pcToOffset(pc());
    96     IonSpew(IonSpew_Snapshots, "Writing pc offset %u, nslots %u", pcoff, nallocs);
    97     writer.writeUnsigned(pcoff);
    98     writer.writeUnsigned(nallocs);
    99     return true;
   100 }
   102 RResumePoint::RResumePoint(CompactBufferReader &reader)
   103 {
   104     static_assert(sizeof(*this) <= sizeof(RInstructionStorage),
   105                   "Storage space is too small to decode this recover instruction.");
   106     pcOffset_ = reader.readUnsigned();
   107     numOperands_ = reader.readUnsigned();
   108     IonSpew(IonSpew_Snapshots, "Read RResumePoint (pc offset %u, nslots %u)",
   109             pcOffset_, numOperands_);
   110 }

mercurial