tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

RematerializedFrame.cpp (6430B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      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/. */
      6 
      7 #include "jit/RematerializedFrame.h"
      8 
      9 #include <algorithm>
     10 #include <utility>
     11 
     12 #include "jit/Bailouts.h"
     13 #include "jit/JSJitFrameIter.h"
     14 #include "js/friend/DumpFunctions.h"  // js::DumpValue
     15 #include "vm/ArgumentsObject.h"
     16 
     17 #include "vm/EnvironmentObject-inl.h"
     18 #include "vm/JSScript-inl.h"
     19 
     20 using namespace js;
     21 using namespace jit;
     22 
     23 struct CopyValueToRematerializedFrame {
     24  Value* slots;
     25 
     26  explicit CopyValueToRematerializedFrame(Value* slots) : slots(slots) {}
     27 
     28  void operator()(const Value& v) { *slots++ = v; }
     29 };
     30 
     31 RematerializedFrame::RematerializedFrame(JSContext* cx, uint8_t* top,
     32                                         unsigned numActualArgs,
     33                                         InlineFrameIterator& iter,
     34                                         MaybeReadFallback& fallback)
     35    : prevUpToDate_(false),
     36      isDebuggee_(iter.script()->isDebuggee()),
     37      hasInitialEnv_(false),
     38      isConstructing_(iter.isConstructing()),
     39      hasCachedSavedFrame_(false),
     40      top_(top),
     41      pc_(iter.pc()),
     42      frameNo_(iter.frameNo()),
     43      numActualArgs_(numActualArgs),
     44      script_(iter.script()),
     45      envChain_(nullptr),
     46      argsObj_(nullptr) {
     47  if (iter.isFunctionFrame()) {
     48    callee_ = iter.callee(fallback);
     49  } else {
     50    callee_ = nullptr;
     51  }
     52 
     53  CopyValueToRematerializedFrame op(slots_);
     54  iter.readFrameArgsAndLocals(
     55      cx, op, op, &envChain_, &hasInitialEnv_, &returnValue_, &argsObj_,
     56      &thisArgument_, ReadFrameArgsBehavior::ActualsAndFormals, fallback);
     57 }
     58 
     59 /* static */
     60 RematerializedFrame* RematerializedFrame::New(JSContext* cx, uint8_t* top,
     61                                              InlineFrameIterator& iter,
     62                                              MaybeReadFallback& fallback) {
     63  unsigned numFormals =
     64      iter.isFunctionFrame() ? iter.calleeTemplate()->nargs() : 0;
     65  unsigned argSlots = std::max(numFormals, iter.numActualArgs());
     66  unsigned extraSlots = argSlots + iter.script()->nfixed();
     67 
     68  // One Value slot is included in sizeof(RematerializedFrame), so we can
     69  // reduce the extra slot count by one.  However, if there are zero slot
     70  // allocations total, then reducing the slots by one will lead to
     71  // the memory allocation being smaller  than sizeof(RematerializedFrame).
     72  if (extraSlots > 0) {
     73    extraSlots -= 1;
     74  }
     75 
     76  RematerializedFrame* buf =
     77      cx->pod_calloc_with_extra<RematerializedFrame, Value>(extraSlots);
     78  if (!buf) {
     79    return nullptr;
     80  }
     81 
     82  return new (buf)
     83      RematerializedFrame(cx, top, iter.numActualArgs(), iter, fallback);
     84 }
     85 
     86 /* static */
     87 bool RematerializedFrame::RematerializeInlineFrames(
     88    JSContext* cx, uint8_t* top, InlineFrameIterator& iter,
     89    MaybeReadFallback& fallback, RematerializedFrameVector& frames) {
     90  Rooted<RematerializedFrameVector> tempFrames(cx,
     91                                               RematerializedFrameVector(cx));
     92  if (!tempFrames.resize(iter.frameCount())) {
     93    return false;
     94  }
     95 
     96  while (true) {
     97    size_t frameNo = iter.frameNo();
     98    tempFrames[frameNo].reset(
     99        RematerializedFrame::New(cx, top, iter, fallback));
    100    if (!tempFrames[frameNo]) {
    101      return false;
    102    }
    103    if (tempFrames[frameNo]->environmentChain()) {
    104      if (!EnsureHasEnvironmentObjects(cx, tempFrames[frameNo].get().get())) {
    105        return false;
    106      }
    107    }
    108 
    109    if (!iter.more()) {
    110      break;
    111    }
    112    ++iter;
    113  }
    114 
    115  frames = std::move(tempFrames.get());
    116  return true;
    117 }
    118 
    119 CallObject& RematerializedFrame::callObj() const {
    120  MOZ_ASSERT(hasInitialEnvironment());
    121  MOZ_ASSERT(callee()->needsCallObject());
    122 
    123  JSObject* env = environmentChain();
    124  while (!env->is<CallObject>()) {
    125    env = env->enclosingEnvironment();
    126  }
    127  return env->as<CallObject>();
    128 }
    129 
    130 bool RematerializedFrame::initFunctionEnvironmentObjects(JSContext* cx) {
    131  return js::InitFunctionEnvironmentObjects(cx, this);
    132 }
    133 
    134 bool RematerializedFrame::pushVarEnvironment(JSContext* cx,
    135                                             Handle<Scope*> scope) {
    136  return js::PushVarEnvironmentObject(cx, scope, this);
    137 }
    138 
    139 void RematerializedFrame::trace(JSTracer* trc) {
    140  TraceRoot(trc, &script_, "remat ion frame script");
    141  TraceRoot(trc, &envChain_, "remat ion frame env chain");
    142  if (callee_) {
    143    TraceRoot(trc, &callee_, "remat ion frame callee");
    144  }
    145  if (argsObj_) {
    146    TraceRoot(trc, &argsObj_, "remat ion frame argsobj");
    147  }
    148  TraceRoot(trc, &returnValue_, "remat ion frame return value");
    149  TraceRoot(trc, &thisArgument_, "remat ion frame this");
    150  TraceRootRange(trc, numArgSlots() + script_->nfixed(), slots_,
    151                 "remat ion frame stack");
    152 }
    153 
    154 void RematerializedFrame::dump() {
    155  fprintf(stderr, " Rematerialized Ion Frame%s\n",
    156          inlined() ? " (inlined)" : "");
    157  if (isFunctionFrame()) {
    158    fprintf(stderr, "  callee fun: ");
    159 #ifdef DEBUG
    160    DumpValue(ObjectValue(*callee()));
    161 #else
    162    fprintf(stderr, "?\n");
    163 #endif
    164  } else {
    165    fprintf(stderr, "  global frame, no callee\n");
    166  }
    167 
    168  fprintf(stderr, "  file %s line %u offset %zu\n", script()->filename(),
    169          script()->lineno(), script()->pcToOffset(pc()));
    170 
    171  fprintf(stderr, "  script = %p\n", (void*)script());
    172 
    173  if (isFunctionFrame()) {
    174    fprintf(stderr, "  env chain: ");
    175 #ifdef DEBUG
    176    DumpValue(ObjectValue(*environmentChain()));
    177 #else
    178    fprintf(stderr, "?\n");
    179 #endif
    180 
    181    if (hasArgsObj()) {
    182      fprintf(stderr, "  args obj: ");
    183 #ifdef DEBUG
    184      DumpValue(ObjectValue(argsObj()));
    185 #else
    186      fprintf(stderr, "?\n");
    187 #endif
    188    }
    189 
    190    fprintf(stderr, "  this: ");
    191 #ifdef DEBUG
    192    DumpValue(thisArgument());
    193 #else
    194    fprintf(stderr, "?\n");
    195 #endif
    196 
    197    for (unsigned i = 0; i < numActualArgs(); i++) {
    198      if (i < numFormalArgs()) {
    199        fprintf(stderr, "  formal (arg %u): ", i);
    200      } else {
    201        fprintf(stderr, "  overflown (arg %u): ", i);
    202      }
    203 #ifdef DEBUG
    204      DumpValue(argv()[i]);
    205 #else
    206      fprintf(stderr, "?\n");
    207 #endif
    208    }
    209 
    210    for (unsigned i = 0; i < script()->nfixed(); i++) {
    211      fprintf(stderr, "  local %u: ", i);
    212 #ifdef DEBUG
    213      DumpValue(locals()[i]);
    214 #else
    215      fprintf(stderr, "?\n");
    216 #endif
    217    }
    218  }
    219 
    220  fputc('\n', stderr);
    221 }