Bug 1865597 - Add error checking when initializing parallel marking and disable on...
[gecko.git] / js / src / frontend / BytecodeSection.cpp
blob7ffefc6fcccf6d373f76f3d1fcf10b1657b01d04
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 "frontend/BytecodeSection.h"
9 #include "mozilla/Assertions.h" // MOZ_ASSERT
11 #include "frontend/AbstractScopePtr.h" // ScopeIndex
12 #include "frontend/CompilationStencil.h" // CompilationStencil
13 #include "frontend/FrontendContext.h" // FrontendContext
14 #include "frontend/SharedContext.h" // FunctionBox
15 #include "js/ColumnNumber.h" // JS::LimitedColumnNumberOneOrigin
16 #include "vm/BytecodeUtil.h" // INDEX_LIMIT, StackUses, StackDefs
17 #include "vm/GlobalObject.h"
18 #include "vm/JSContext.h" // JSContext
19 #include "vm/RegExpObject.h" // RegexpObject
20 #include "vm/Scope.h" // GlobalScope
22 using namespace js;
23 using namespace js::frontend;
25 bool GCThingList::append(FunctionBox* funbox, GCThingIndex* index) {
26 // Append the function to the vector and return the index in *index.
27 *index = GCThingIndex(vector.length());
29 if (!vector.emplaceBack(funbox->index())) {
30 return false;
32 return true;
35 AbstractScopePtr GCThingList::getScope(size_t index) const {
36 const TaggedScriptThingIndex& elem = vector[index];
37 if (elem.isEmptyGlobalScope()) {
38 // The empty enclosing scope should be stored by
39 // CompilationInput::initForSelfHostingGlobal.
40 return AbstractScopePtr::compilationEnclosingScope(compilationState);
42 return AbstractScopePtr(compilationState, elem.toScope());
45 mozilla::Maybe<ScopeIndex> GCThingList::getScopeIndex(size_t index) const {
46 const TaggedScriptThingIndex& elem = vector[index];
47 if (elem.isEmptyGlobalScope()) {
48 return mozilla::Nothing();
50 return mozilla::Some(vector[index].toScope());
53 TaggedParserAtomIndex GCThingList::getAtom(size_t index) const {
54 const TaggedScriptThingIndex& elem = vector[index];
55 return elem.toAtom();
58 bool js::frontend::EmitScriptThingsVector(
59 JSContext* cx, const CompilationAtomCache& atomCache,
60 const CompilationStencil& stencil, CompilationGCOutput& gcOutput,
61 mozilla::Span<const TaggedScriptThingIndex> things,
62 mozilla::Span<JS::GCCellPtr> output) {
63 MOZ_ASSERT(things.size() <= INDEX_LIMIT);
64 MOZ_ASSERT(things.size() == output.size());
66 for (uint32_t i = 0; i < things.size(); i++) {
67 const auto& thing = things[i];
68 switch (thing.tag()) {
69 case TaggedScriptThingIndex::Kind::ParserAtomIndex:
70 case TaggedScriptThingIndex::Kind::WellKnown: {
71 JSString* str = atomCache.getExistingStringAt(cx, thing.toAtom());
72 MOZ_ASSERT(str);
73 output[i] = JS::GCCellPtr(str);
74 break;
76 case TaggedScriptThingIndex::Kind::Null:
77 output[i] = JS::GCCellPtr(nullptr);
78 break;
79 case TaggedScriptThingIndex::Kind::BigInt: {
80 const BigIntStencil& data = stencil.bigIntData[thing.toBigInt()];
81 BigInt* bi = data.createBigInt(cx);
82 if (!bi) {
83 return false;
85 output[i] = JS::GCCellPtr(bi);
86 break;
88 case TaggedScriptThingIndex::Kind::ObjLiteral: {
89 const ObjLiteralStencil& data =
90 stencil.objLiteralData[thing.toObjLiteral()];
91 JS::GCCellPtr ptr = data.create(cx, atomCache);
92 if (!ptr) {
93 return false;
95 output[i] = ptr;
96 break;
98 case TaggedScriptThingIndex::Kind::RegExp: {
99 RegExpStencil& data = stencil.regExpData[thing.toRegExp()];
100 RegExpObject* regexp = data.createRegExp(cx, atomCache);
101 if (!regexp) {
102 return false;
104 output[i] = JS::GCCellPtr(regexp);
105 break;
107 case TaggedScriptThingIndex::Kind::Scope:
108 output[i] = JS::GCCellPtr(gcOutput.getScope(thing.toScope()));
109 break;
110 case TaggedScriptThingIndex::Kind::Function:
111 output[i] = JS::GCCellPtr(gcOutput.getFunction(thing.toFunction()));
112 break;
113 case TaggedScriptThingIndex::Kind::EmptyGlobalScope: {
114 Scope* scope = &cx->global()->emptyGlobalScope();
115 output[i] = JS::GCCellPtr(scope);
116 break;
121 return true;
124 bool CGTryNoteList::append(TryNoteKind kind, uint32_t stackDepth,
125 BytecodeOffset start, BytecodeOffset end) {
126 MOZ_ASSERT(start <= end);
128 // Offsets are given relative to sections, but we only expect main-section
129 // to have TryNotes. In finish() we will fixup base offset.
131 TryNote note(uint32_t(kind), stackDepth, start.toUint32(),
132 (end - start).toUint32());
134 return list.append(note);
137 bool CGScopeNoteList::append(GCThingIndex scopeIndex, BytecodeOffset offset,
138 uint32_t parent) {
139 ScopeNote note;
140 note.index = scopeIndex;
141 note.start = offset.toUint32();
142 note.length = 0;
143 note.parent = parent;
145 return list.append(note);
148 void CGScopeNoteList::recordEnd(uint32_t index, BytecodeOffset offset) {
149 recordEndImpl(index, offset.toUint32());
152 void CGScopeNoteList::recordEndFunctionBodyVar(uint32_t index) {
153 recordEndImpl(index, UINT32_MAX);
156 void CGScopeNoteList::recordEndImpl(uint32_t index, uint32_t offset) {
157 MOZ_ASSERT(index < length());
158 MOZ_ASSERT(list[index].length == 0);
159 MOZ_ASSERT(offset >= list[index].start);
160 list[index].length = offset - list[index].start;
163 BytecodeSection::BytecodeSection(FrontendContext* fc, uint32_t lineNum,
164 JS::LimitedColumnNumberOneOrigin column)
165 : code_(fc),
166 notes_(fc),
167 lastNoteOffset_(0),
168 tryNoteList_(fc),
169 scopeNoteList_(fc),
170 resumeOffsetList_(fc),
171 currentLine_(lineNum),
172 lastColumn_(column) {}
174 void BytecodeSection::updateDepth(JSOp op, BytecodeOffset target) {
175 jsbytecode* pc = code(target);
177 int nuses = StackUses(op, pc);
178 int ndefs = StackDefs(op);
180 stackDepth_ -= nuses;
181 MOZ_ASSERT(stackDepth_ >= 0);
182 stackDepth_ += ndefs;
184 if (uint32_t(stackDepth_) > maxStackDepth_) {
185 maxStackDepth_ = stackDepth_;
189 PerScriptData::PerScriptData(FrontendContext* fc,
190 frontend::CompilationState& compilationState)
191 : gcThingList_(fc, compilationState),
192 atomIndices_(fc->nameCollectionPool()) {}
194 bool PerScriptData::init(FrontendContext* fc) {
195 return atomIndices_.acquire(fc);