1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
Copied from: https://hg.mozilla.org/releases/mozilla-esr38/rev/0f7224441f20
Security advisory: https://www.mozilla.org/en-US/security/advisories/mfsa2016-01/
Mozilla Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1234280
# HG changeset patch
# User Benjamin Bouvier <benj@benj.me>
# Date 1450947090 -3600
# Node ID 0f7224441f2089001f7934b46ac10cb72d267606
# Parent debff255c08e898be370e307e1e014f5601c20c6
Bug 1234280: Handle oom in CodeGeneratorShared::allocateData; r=jandem, a=sledru
diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -7902,17 +7902,19 @@ const VMFunction GetPropertyIC::UpdateIn
void
CodeGenerator::visitGetPropertyIC(OutOfLineUpdateCache* ool, DataPtr<GetPropertyIC>& ic)
{
LInstruction* lir = ool->lir();
if (ic->idempotent()) {
size_t numLocs;
CacheLocationList& cacheLocs = lir->mirRaw()->toGetPropertyCache()->location();
- size_t locationBase = addCacheLocations(cacheLocs, &numLocs);
+ size_t locationBase;
+ if (!addCacheLocations(cacheLocs, &numLocs, &locationBase))
+ return;
ic->setLocationInfo(locationBase, numLocs);
}
saveLive(lir);
pushArg(ic->object());
pushArg(Imm32(ool->getCacheIndex()));
pushArg(ImmGCPtr(gen->info().script()));
diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -1527,31 +1527,34 @@ CodeGeneratorShared::jumpToBlock(MBasicB
masm.propagateOOM(patchableBackedges_.append(PatchableBackedgeInfo(backedge, mir->lir()->label(), oolEntry)));
} else {
masm.j(cond, mir->lir()->label());
}
}
#endif
-size_t
-CodeGeneratorShared::addCacheLocations(const CacheLocationList& locs, size_t* numLocs)
+MOZ_WARN_UNUSED_RESULT bool
+CodeGeneratorShared::addCacheLocations(const CacheLocationList& locs, size_t* numLocs,
+ size_t* curIndex)
{
size_t firstIndex = runtimeData_.length();
size_t numLocations = 0;
for (CacheLocationList::iterator iter = locs.begin(); iter != locs.end(); iter++) {
// allocateData() ensures that sizeof(CacheLocation) is word-aligned.
// If this changes, we will need to pad to ensure alignment.
- size_t curIndex = allocateData(sizeof(CacheLocation));
- new (&runtimeData_[curIndex]) CacheLocation(iter->pc, iter->script);
+ if (!allocateData(sizeof(CacheLocation), curIndex))
+ return false;
+ new (&runtimeData_[*curIndex]) CacheLocation(iter->pc, iter->script);
numLocations++;
}
MOZ_ASSERT(numLocations != 0);
*numLocs = numLocations;
- return firstIndex;
+ *curIndex = firstIndex;
+ return true;
}
ReciprocalMulConstants
CodeGeneratorShared::computeDivisionConstants(int d) {
// In what follows, d is positive and is not a power of 2.
MOZ_ASSERT(d > 0 && (d & (d - 1)) != 0);
// Speeding up division by non power-of-2 constants is possible by
diff --git a/js/src/jit/shared/CodeGenerator-shared.h b/js/src/jit/shared/CodeGenerator-shared.h
--- a/js/src/jit/shared/CodeGenerator-shared.h
+++ b/js/src/jit/shared/CodeGenerator-shared.h
@@ -3,16 +3,17 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef jit_shared_CodeGenerator_shared_h
#define jit_shared_CodeGenerator_shared_h
#include "mozilla/Alignment.h"
+#include "mozilla/TypeTraits.h"
#include "jit/JitFrames.h"
#include "jit/LIR.h"
#include "jit/MacroAssembler.h"
#include "jit/MIRGenerator.h"
#include "jit/MIRGraph.h"
#include "jit/OptimizationTracking.h"
#include "jit/Safepoints.h"
@@ -242,24 +243,16 @@ class CodeGeneratorShared : public LElem
return SlotToStackOffset(a->toStackSlot()->slot());
}
uint32_t frameSize() const {
return frameClass_ == FrameSizeClass::None() ? frameDepth_ : frameClass_.frameSize();
}
protected:
- // Ensure the cache is an IonCache while expecting the size of the derived
- // class. We only need the cache list at GC time. Everyone else can just take
- // runtimeData offsets.
- size_t allocateCache(const IonCache&, size_t size) {
- size_t dataOffset = allocateData(size);
- masm.propagateOOM(cacheList_.append(dataOffset));
- return dataOffset;
- }
#ifdef CHECK_OSIPOINT_REGISTERS
void resetOsiPointRegs(LSafepoint* safepoint);
bool shouldVerifyOsiPointRegs(LSafepoint* safepoint);
void verifyOsiPointRegs(LSafepoint* safepoint);
#endif
bool addNativeToBytecodeEntry(const BytecodeSite* site);
@@ -295,27 +288,33 @@ class CodeGeneratorShared : public LElem
return lookup();
}
T * operator*() {
return lookup();
}
};
protected:
-
- size_t allocateData(size_t size) {
+ MOZ_WARN_UNUSED_RESULT
+ bool allocateData(size_t size, size_t* offset) {
MOZ_ASSERT(size % sizeof(void*) == 0);
- size_t dataOffset = runtimeData_.length();
+ *offset = runtimeData_.length();
masm.propagateOOM(runtimeData_.appendN(0, size));
- return dataOffset;
+ return !masm.oom();
}
+ // Ensure the cache is an IonCache while expecting the size of the derived
+ // class. We only need the cache list at GC time. Everyone else can just take
+ // runtimeData offsets.
template <typename T>
inline size_t allocateCache(const T& cache) {
- size_t index = allocateCache(cache, sizeof(mozilla::AlignedStorage2<T>));
+ static_assert(mozilla::IsBaseOf<IonCache, T>::value, "T must inherit from IonCache");
+ size_t index;
+ masm.propagateOOM(allocateData(sizeof(mozilla::AlignedStorage2<T>), &index));
+ masm.propagateOOM(cacheList_.append(index));
if (masm.oom())
return SIZE_MAX;
// Use the copy constructor on the allocated space.
MOZ_ASSERT(index == cacheList_.back());
new (&runtimeData_[index]) T(cache);
return index;
}
@@ -475,17 +474,17 @@ class CodeGeneratorShared : public LElem
void callVM(const VMFunction& f, LInstruction* ins, const Register* dynStack = nullptr);
template <class ArgSeq, class StoreOutputTo>
inline OutOfLineCode* oolCallVM(const VMFunction& fun, LInstruction* ins, const ArgSeq& args,
const StoreOutputTo& out);
void addCache(LInstruction* lir, size_t cacheIndex);
- size_t addCacheLocations(const CacheLocationList& locs, size_t* numLocs);
+ bool addCacheLocations(const CacheLocationList& locs, size_t* numLocs, size_t* offset);
ReciprocalMulConstants computeDivisionConstants(int d);
protected:
void addOutOfLineCode(OutOfLineCode* code, const MInstruction* mir);
void addOutOfLineCode(OutOfLineCode* code, const BytecodeSite* site);
bool hasOutOfLineCode() { return !outOfLineCode_.empty(); }
bool generateOutOfLineCode();
|