Line data Source code
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/. */
6 :
7 : #ifndef jit_shared_BaselineCompiler_shared_h
8 : #define jit_shared_BaselineCompiler_shared_h
9 :
10 : #include "jit/BaselineFrameInfo.h"
11 : #include "jit/BaselineIC.h"
12 : #include "jit/BytecodeAnalysis.h"
13 : #include "jit/MacroAssembler.h"
14 :
15 : namespace js {
16 : namespace jit {
17 :
18 628 : class BaselineCompilerShared
19 : {
20 : protected:
21 : JSContext* cx;
22 : JSScript* script;
23 : jsbytecode* pc;
24 : MacroAssembler masm;
25 : bool ionCompileable_;
26 : bool ionOSRCompileable_;
27 : bool compileDebugInstrumentation_;
28 :
29 : TempAllocator& alloc_;
30 : BytecodeAnalysis analysis_;
31 : FrameInfo frame;
32 :
33 : FallbackICStubSpace stubSpace_;
34 : js::Vector<BaselineICEntry, 16, SystemAllocPolicy> icEntries_;
35 :
36 : // Stores the native code offset for a bytecode pc.
37 61179 : struct PCMappingEntry
38 : {
39 : uint32_t pcOffset;
40 : uint32_t nativeOffset;
41 : PCMappingSlotInfo slotInfo;
42 :
43 : // If set, insert a PCMappingIndexEntry before encoding the
44 : // current entry.
45 : bool addIndexEntry;
46 : };
47 :
48 : js::Vector<PCMappingEntry, 16, SystemAllocPolicy> pcMappingEntries_;
49 :
50 : // Labels for the 'movWithPatch' for loading IC entry pointers in
51 : // the generated IC-calling code in the main jitcode. These need
52 : // to be patched with the actual icEntry offsets after the BaselineScript
53 : // has been allocated.
54 19345 : struct ICLoadLabel {
55 : size_t icEntry;
56 : CodeOffset label;
57 : };
58 : js::Vector<ICLoadLabel, 16, SystemAllocPolicy> icLoadLabels_;
59 :
60 : uint32_t pushedBeforeCall_;
61 : #ifdef DEBUG
62 : bool inCall_;
63 : #endif
64 :
65 : CodeOffset profilerPushToggleOffset_;
66 : CodeOffset profilerEnterFrameToggleOffset_;
67 : CodeOffset profilerExitFrameToggleOffset_;
68 :
69 : Vector<CodeOffset> traceLoggerToggleOffsets_;
70 : CodeOffset traceLoggerScriptTextIdOffset_;
71 :
72 : BaselineCompilerShared(JSContext* cx, TempAllocator& alloc, JSScript* script);
73 :
74 19345 : BaselineICEntry* allocateICEntry(ICStub* stub, ICEntry::Kind kind) {
75 19345 : if (!stub)
76 0 : return nullptr;
77 :
78 : // Create the entry and add it to the vector.
79 19345 : if (!icEntries_.append(BaselineICEntry(script->pcToOffset(pc), kind))) {
80 0 : ReportOutOfMemory(cx);
81 0 : return nullptr;
82 : }
83 19345 : BaselineICEntry& vecEntry = icEntries_.back();
84 :
85 : // Set the first stub for the IC entry to the fallback stub
86 19345 : vecEntry.setFirstStub(stub);
87 :
88 : // Return pointer to the IC entry
89 19345 : return &vecEntry;
90 : }
91 :
92 : // Append an ICEntry without a stub.
93 3440 : bool appendICEntry(ICEntry::Kind kind, uint32_t returnOffset) {
94 3440 : BaselineICEntry entry(script->pcToOffset(pc), kind);
95 3440 : entry.setReturnOffset(CodeOffset(returnOffset));
96 3440 : if (!icEntries_.append(entry)) {
97 0 : ReportOutOfMemory(cx);
98 0 : return false;
99 : }
100 3440 : return true;
101 : }
102 :
103 19345 : bool addICLoadLabel(CodeOffset label) {
104 19345 : MOZ_ASSERT(!icEntries_.empty());
105 19345 : ICLoadLabel loadLabel;
106 19345 : loadLabel.label = label;
107 19345 : loadLabel.icEntry = icEntries_.length() - 1;
108 19345 : if (!icLoadLabels_.append(loadLabel)) {
109 0 : ReportOutOfMemory(cx);
110 0 : return false;
111 : }
112 19345 : return true;
113 : }
114 :
115 4361 : JSFunction* function() const {
116 : // Not delazifying here is ok as the function is guaranteed to have
117 : // been delazified before compilation started.
118 4361 : return script->functionNonDelazifying();
119 : }
120 :
121 5 : ModuleObject* module() const {
122 5 : return script->module();
123 : }
124 :
125 61179 : PCMappingSlotInfo getStackTopSlotInfo() {
126 61179 : MOZ_ASSERT(frame.numUnsyncedSlots() <= 2);
127 61179 : switch (frame.numUnsyncedSlots()) {
128 : case 0:
129 22871 : return PCMappingSlotInfo::MakeSlotInfo();
130 : case 1:
131 24743 : return PCMappingSlotInfo::MakeSlotInfo(PCMappingSlotInfo::ToSlotLocation(frame.peek(-1)));
132 : case 2:
133 : default:
134 13565 : return PCMappingSlotInfo::MakeSlotInfo(PCMappingSlotInfo::ToSlotLocation(frame.peek(-1)),
135 27130 : PCMappingSlotInfo::ToSlotLocation(frame.peek(-2)));
136 : }
137 : }
138 :
139 : template <typename T>
140 4293 : void pushArg(const T& t) {
141 4293 : masm.Push(t);
142 4293 : }
143 : void prepareVMCall();
144 :
145 : enum CallVMPhase {
146 : POST_INITIALIZE,
147 : PRE_INITIALIZE,
148 : CHECK_OVER_RECURSED
149 : };
150 : bool callVM(const VMFunction& fun, CallVMPhase phase=POST_INITIALIZE);
151 :
152 698 : bool callVMNonOp(const VMFunction& fun, CallVMPhase phase=POST_INITIALIZE) {
153 698 : if (!callVM(fun, phase))
154 0 : return false;
155 698 : icEntries_.back().setFakeKind(ICEntry::Kind_NonOpCallVM);
156 698 : return true;
157 : }
158 :
159 : public:
160 : BytecodeAnalysis& analysis() {
161 : return analysis_;
162 : }
163 :
164 0 : void setCompileDebugInstrumentation() {
165 0 : compileDebugInstrumentation_ = true;
166 0 : }
167 : };
168 :
169 : } // namespace jit
170 : } // namespace js
171 :
172 : #endif /* jit_shared_BaselineCompiler_shared_h */
|