|
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/IonMacroAssembler.h" |
|
14 |
|
15 namespace js { |
|
16 namespace jit { |
|
17 |
|
18 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 debugMode_; |
|
28 |
|
29 TempAllocator &alloc_; |
|
30 BytecodeAnalysis analysis_; |
|
31 FrameInfo frame; |
|
32 |
|
33 FallbackICStubSpace stubSpace_; |
|
34 js::Vector<ICEntry, 16, SystemAllocPolicy> icEntries_; |
|
35 |
|
36 // Stores the native code offset for a bytecode pc. |
|
37 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 void fixupNativeOffset(MacroAssembler &masm) { |
|
48 CodeOffsetLabel offset(nativeOffset); |
|
49 offset.fixup(&masm); |
|
50 JS_ASSERT(offset.offset() <= UINT32_MAX); |
|
51 nativeOffset = (uint32_t) offset.offset(); |
|
52 } |
|
53 }; |
|
54 |
|
55 js::Vector<PCMappingEntry, 16, SystemAllocPolicy> pcMappingEntries_; |
|
56 |
|
57 // Labels for the 'movWithPatch' for loading IC entry pointers in |
|
58 // the generated IC-calling code in the main jitcode. These need |
|
59 // to be patched with the actual icEntry offsets after the BaselineScript |
|
60 // has been allocated. |
|
61 struct ICLoadLabel { |
|
62 size_t icEntry; |
|
63 CodeOffsetLabel label; |
|
64 }; |
|
65 js::Vector<ICLoadLabel, 16, SystemAllocPolicy> icLoadLabels_; |
|
66 |
|
67 uint32_t pushedBeforeCall_; |
|
68 mozilla::DebugOnly<bool> inCall_; |
|
69 |
|
70 CodeOffsetLabel spsPushToggleOffset_; |
|
71 |
|
72 BaselineCompilerShared(JSContext *cx, TempAllocator &alloc, JSScript *script); |
|
73 |
|
74 ICEntry *allocateICEntry(ICStub *stub, ICEntry::Kind kind) { |
|
75 if (!stub) |
|
76 return nullptr; |
|
77 |
|
78 // Create the entry and add it to the vector. |
|
79 if (!icEntries_.append(ICEntry(script->pcToOffset(pc), kind))) |
|
80 return nullptr; |
|
81 ICEntry &vecEntry = icEntries_.back(); |
|
82 |
|
83 // Set the first stub for the IC entry to the fallback stub |
|
84 vecEntry.setFirstStub(stub); |
|
85 |
|
86 // Return pointer to the IC entry |
|
87 return &vecEntry; |
|
88 } |
|
89 |
|
90 bool addICLoadLabel(CodeOffsetLabel label) { |
|
91 JS_ASSERT(!icEntries_.empty()); |
|
92 ICLoadLabel loadLabel; |
|
93 loadLabel.label = label; |
|
94 loadLabel.icEntry = icEntries_.length() - 1; |
|
95 return icLoadLabels_.append(loadLabel); |
|
96 } |
|
97 |
|
98 JSFunction *function() const { |
|
99 // Not delazifying here is ok as the function is guaranteed to have |
|
100 // been delazified before compilation started. |
|
101 return script->functionNonDelazifying(); |
|
102 } |
|
103 |
|
104 PCMappingSlotInfo getStackTopSlotInfo() { |
|
105 JS_ASSERT(frame.numUnsyncedSlots() <= 2); |
|
106 switch (frame.numUnsyncedSlots()) { |
|
107 case 0: |
|
108 return PCMappingSlotInfo::MakeSlotInfo(); |
|
109 case 1: |
|
110 return PCMappingSlotInfo::MakeSlotInfo(PCMappingSlotInfo::ToSlotLocation(frame.peek(-1))); |
|
111 case 2: |
|
112 default: |
|
113 return PCMappingSlotInfo::MakeSlotInfo(PCMappingSlotInfo::ToSlotLocation(frame.peek(-1)), |
|
114 PCMappingSlotInfo::ToSlotLocation(frame.peek(-2))); |
|
115 } |
|
116 } |
|
117 |
|
118 template <typename T> |
|
119 void pushArg(const T& t) { |
|
120 masm.Push(t); |
|
121 } |
|
122 void prepareVMCall() { |
|
123 pushedBeforeCall_ = masm.framePushed(); |
|
124 inCall_ = true; |
|
125 |
|
126 // Ensure everything is synced. |
|
127 frame.syncStack(0); |
|
128 |
|
129 // Save the frame pointer. |
|
130 masm.Push(BaselineFrameReg); |
|
131 } |
|
132 |
|
133 enum CallVMPhase { |
|
134 POST_INITIALIZE, |
|
135 PRE_INITIALIZE, |
|
136 CHECK_OVER_RECURSED |
|
137 }; |
|
138 bool callVM(const VMFunction &fun, CallVMPhase phase=POST_INITIALIZE); |
|
139 |
|
140 public: |
|
141 BytecodeAnalysis &analysis() { |
|
142 return analysis_; |
|
143 } |
|
144 }; |
|
145 |
|
146 } // namespace jit |
|
147 } // namespace js |
|
148 |
|
149 #endif /* jit_shared_BaselineCompiler_shared_h */ |