Bug 1865597 - Add error checking when initializing parallel marking and disable on...
[gecko.git] / js / src / jit / RematerializedFrame.cpp
blobc9544057f7dfbae247a5b486a52bf8048f687fa4
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/. */
7 #include "jit/RematerializedFrame.h"
9 #include <algorithm>
10 #include <utility>
12 #include "jit/Bailouts.h"
13 #include "jit/JSJitFrameIter.h"
14 #include "js/friend/DumpFunctions.h" // js::DumpValue
15 #include "vm/ArgumentsObject.h"
17 #include "vm/EnvironmentObject-inl.h"
18 #include "vm/JSScript-inl.h"
20 using namespace js;
21 using namespace jit;
23 struct CopyValueToRematerializedFrame {
24 Value* slots;
26 explicit CopyValueToRematerializedFrame(Value* slots) : slots(slots) {}
28 void operator()(const Value& v) { *slots++ = v; }
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;
53 CopyValueToRematerializedFrame op(slots_);
54 iter.readFrameArgsAndLocals(
55 cx, op, op, &envChain_, &hasInitialEnv_, &returnValue_, &argsObj_,
56 &thisArgument_, ReadFrameArgsBehavior::ActualsAndFormals, fallback);
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();
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;
76 RematerializedFrame* buf =
77 cx->pod_calloc_with_extra<RematerializedFrame, Value>(extraSlots);
78 if (!buf) {
79 return nullptr;
82 return new (buf)
83 RematerializedFrame(cx, top, iter.numActualArgs(), iter, fallback);
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;
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;
103 if (tempFrames[frameNo]->environmentChain()) {
104 if (!EnsureHasEnvironmentObjects(cx, tempFrames[frameNo].get().get())) {
105 return false;
109 if (!iter.more()) {
110 break;
112 ++iter;
115 frames = std::move(tempFrames.get());
116 return true;
119 CallObject& RematerializedFrame::callObj() const {
120 MOZ_ASSERT(hasInitialEnvironment());
121 MOZ_ASSERT(callee()->needsCallObject());
123 JSObject* env = environmentChain();
124 while (!env->is<CallObject>()) {
125 env = env->enclosingEnvironment();
127 return env->as<CallObject>();
130 bool RematerializedFrame::initFunctionEnvironmentObjects(JSContext* cx) {
131 return js::InitFunctionEnvironmentObjects(cx, this);
134 bool RematerializedFrame::pushVarEnvironment(JSContext* cx,
135 Handle<Scope*> scope) {
136 return js::PushVarEnvironmentObject(cx, scope, this);
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");
145 if (argsObj_) {
146 TraceRoot(trc, &argsObj_, "remat ion frame argsobj");
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");
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");
168 fprintf(stderr, " file %s line %u offset %zu\n", script()->filename(),
169 script()->lineno(), script()->pcToOffset(pc()));
171 fprintf(stderr, " script = %p\n", (void*)script());
173 if (isFunctionFrame()) {
174 fprintf(stderr, " env chain: ");
175 #ifdef DEBUG
176 DumpValue(ObjectValue(*environmentChain()));
177 #else
178 fprintf(stderr, "?\n");
179 #endif
181 if (hasArgsObj()) {
182 fprintf(stderr, " args obj: ");
183 #ifdef DEBUG
184 DumpValue(ObjectValue(argsObj()));
185 #else
186 fprintf(stderr, "?\n");
187 #endif
190 fprintf(stderr, " this: ");
191 #ifdef DEBUG
192 DumpValue(thisArgument());
193 #else
194 fprintf(stderr, "?\n");
195 #endif
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);
203 #ifdef DEBUG
204 DumpValue(argv()[i]);
205 #else
206 fprintf(stderr, "?\n");
207 #endif
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
220 fputc('\n', stderr);