summaryrefslogtreecommitdiffstats
path: root/js/src/jit
diff options
context:
space:
mode:
authorjanekptacijarabaci <janekptacijarabaci@seznam.cz>2018-07-06 15:53:52 +0200
committerjanekptacijarabaci <janekptacijarabaci@seznam.cz>2018-07-06 15:53:52 +0200
commit941e54654eabed0a3568f7fefe424a45aa02eddb (patch)
tree49aa02b174c428962d99142d8061267bfcd79e69 /js/src/jit
parentad9ee72dcd7981bc47b3844a224d69fadfdfd8ef (diff)
parent0daa12376295d5d796256a116eb2a348a3a9273f (diff)
downloadUXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar
UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar.gz
UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar.lz
UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar.xz
UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.zip
Merge branch 'master' of https://github.com/MoonchildProductions/UXP into _testBranch_test_1
Diffstat (limited to 'js/src/jit')
-rw-r--r--js/src/jit/BaselineFrameInfo.h4
-rw-r--r--js/src/jit/CodeGenerator.cpp26
-rw-r--r--js/src/jit/CodeGenerator.h1
-rw-r--r--js/src/jit/InlinableNatives.h10
-rw-r--r--js/src/jit/IonBuilder.h1
-rw-r--r--js/src/jit/JitFrameIterator.h2
-rw-r--r--js/src/jit/JitFrames.cpp4
-rw-r--r--js/src/jit/Lowering.cpp10
-rw-r--r--js/src/jit/Lowering.h1
-rw-r--r--js/src/jit/MCallOptimize.cpp51
-rw-r--r--js/src/jit/MIR.h42
-rw-r--r--js/src/jit/MOpcodes.h1
-rw-r--r--js/src/jit/MacroAssembler.cpp6
-rw-r--r--js/src/jit/ProcessExecutableMemory.cpp8
-rw-r--r--js/src/jit/ProcessExecutableMemory.h8
-rw-r--r--js/src/jit/RegisterSets.h8
-rw-r--r--js/src/jit/RematerializedFrame.cpp14
-rw-r--r--js/src/jit/shared/IonAssemblerBuffer.h4
-rw-r--r--js/src/jit/shared/LIR-shared.h23
-rw-r--r--js/src/jit/shared/LOpcodes-shared.h1
-rw-r--r--js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h32
21 files changed, 222 insertions, 35 deletions
diff --git a/js/src/jit/BaselineFrameInfo.h b/js/src/jit/BaselineFrameInfo.h
index 13bf0358d..1691270ac 100644
--- a/js/src/jit/BaselineFrameInfo.h
+++ b/js/src/jit/BaselineFrameInfo.h
@@ -67,7 +67,7 @@ class StackValue
union {
struct {
- Value v;
+ JS::UninitializedValue v;
} constant;
struct {
mozilla::AlignedStorage2<ValueOperand> reg;
@@ -112,7 +112,7 @@ class StackValue
}
Value constant() const {
MOZ_ASSERT(kind_ == Constant);
- return data.constant.v;
+ return data.constant.v.asValueRef();
}
ValueOperand reg() const {
MOZ_ASSERT(kind_ == Register);
diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp
index 7b2f8214b..16d026092 100644
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -11529,6 +11529,32 @@ CodeGenerator::visitHasClass(LHasClass* ins)
}
void
+CodeGenerator::visitGuardToClass(LGuardToClass* ins)
+{
+ Register lhs = ToRegister(ins->lhs());
+ Register output = ToRegister(ins->output());
+ Register temp = ToRegister(ins->temp());
+
+ Label notEqual;
+
+ masm.branchTestObjClass(Assembler::NotEqual, lhs, temp, ins->mir()->getClass(), &notEqual);
+ masm.mov(lhs, output);
+
+ if (ins->mir()->type() == MIRType::Object) {
+ // Can't return null-return here, so bail
+ bailoutFrom(&notEqual, ins->snapshot());
+ } else {
+ Label done;
+ masm.jump(&done);
+
+ masm.bind(&notEqual);
+ masm.mov(ImmPtr(0), output);
+
+ masm.bind(&done);
+ }
+}
+
+void
CodeGenerator::visitWasmParameter(LWasmParameter* lir)
{
}
diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h
index d3126651b..b226f6cc9 100644
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -377,6 +377,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitIsObject(LIsObject* lir);
void visitIsObjectAndBranch(LIsObjectAndBranch* lir);
void visitHasClass(LHasClass* lir);
+ void visitGuardToClass(LGuardToClass* lir);
void visitWasmParameter(LWasmParameter* lir);
void visitWasmParameterI64(LWasmParameterI64* lir);
void visitWasmReturn(LWasmReturn* ret);
diff --git a/js/src/jit/InlinableNatives.h b/js/src/jit/InlinableNatives.h
index 15352c04f..23d3143a7 100644
--- a/js/src/jit/InlinableNatives.h
+++ b/js/src/jit/InlinableNatives.h
@@ -117,13 +117,15 @@
_(IntrinsicDefineDataProperty) \
_(IntrinsicObjectHasPrototype) \
\
- _(IntrinsicIsArrayIterator) \
- _(IntrinsicIsMapIterator) \
- _(IntrinsicIsSetIterator) \
- _(IntrinsicIsStringIterator) \
+ _(IntrinsicGuardToArrayIterator) \
+ _(IntrinsicGuardToMapIterator) \
+ _(IntrinsicGuardToSetIterator) \
+ _(IntrinsicGuardToStringIterator) \
\
+ _(IntrinsicGuardToMapObject) \
_(IntrinsicGetNextMapEntryForIterator) \
\
+ _(IntrinsicGuardToSetObject) \
_(IntrinsicGetNextSetEntryForIterator) \
\
_(IntrinsicArrayBufferByteLength) \
diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h
index 35ad120f7..f24ef30c8 100644
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -969,6 +969,7 @@ class IonBuilder
const Class* clasp2 = nullptr,
const Class* clasp3 = nullptr,
const Class* clasp4 = nullptr);
+ InliningStatus inlineGuardToClass(CallInfo& callInfo, const Class* clasp);
InliningStatus inlineIsConstructing(CallInfo& callInfo);
InliningStatus inlineSubstringKernel(CallInfo& callInfo);
InliningStatus inlineObjectHasPrototype(CallInfo& callInfo);
diff --git a/js/src/jit/JitFrameIterator.h b/js/src/jit/JitFrameIterator.h
index ba5efef6a..3620badbd 100644
--- a/js/src/jit/JitFrameIterator.h
+++ b/js/src/jit/JitFrameIterator.h
@@ -322,9 +322,7 @@ class RInstructionResults
MOZ_MUST_USE bool init(JSContext* cx, uint32_t numResults);
bool isInitialized() const;
-#ifdef DEBUG
size_t length() const;
-#endif
JitFrameLayout* frame() const;
diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp
index f11f17225..019be46dd 100644
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -1688,13 +1688,11 @@ RInstructionResults::isInitialized() const
return initialized_;
}
-#ifdef DEBUG
size_t
RInstructionResults::length() const
{
return results_->length();
}
-#endif
JitFrameLayout*
RInstructionResults::frame() const
@@ -2150,7 +2148,7 @@ SnapshotIterator::initInstructionResults(MaybeReadFallback& fallback)
}
MOZ_ASSERT(results->isInitialized());
- MOZ_ASSERT(results->length() == recover_.numInstructions() - 1);
+ MOZ_RELEASE_ASSERT(results->length() == recover_.numInstructions() - 1);
instructionResults_ = results;
return true;
}
diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp
index 730697163..709de9987 100644
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -4171,6 +4171,16 @@ LIRGenerator::visitHasClass(MHasClass* ins)
}
void
+LIRGenerator::visitGuardToClass(MGuardToClass* ins)
+{
+ MOZ_ASSERT(ins->object()->type() == MIRType::Object);
+ MOZ_ASSERT(ins->type() == MIRType::ObjectOrNull|| ins->type() == MIRType::Object);
+ LGuardToClass* lir = new(alloc()) LGuardToClass(useRegister(ins->object()), temp());
+ assignSnapshot(lir, Bailout_TypeBarrierO);
+ define(lir, ins);
+}
+
+void
LIRGenerator::visitWasmAddOffset(MWasmAddOffset* ins)
{
MOZ_ASSERT(ins->base()->type() == MIRType::Int32);
diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h
index b2805cb7a..9b4095aec 100644
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -289,6 +289,7 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitIsConstructor(MIsConstructor* ins);
void visitIsObject(MIsObject* ins);
void visitHasClass(MHasClass* ins);
+ void visitGuardToClass(MGuardToClass* ins);
void visitWasmAddOffset(MWasmAddOffset* ins);
void visitWasmBoundsCheck(MWasmBoundsCheck* ins);
void visitWasmLoadGlobalVar(MWasmLoadGlobalVar* ins);
diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp
index 293253253..736c6c892 100644
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -280,24 +280,28 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
return inlineIsConstructing(callInfo);
case InlinableNative::IntrinsicSubstringKernel:
return inlineSubstringKernel(callInfo);
- case InlinableNative::IntrinsicIsArrayIterator:
- return inlineHasClass(callInfo, &ArrayIteratorObject::class_);
- case InlinableNative::IntrinsicIsMapIterator:
- return inlineHasClass(callInfo, &MapIteratorObject::class_);
- case InlinableNative::IntrinsicIsSetIterator:
- return inlineHasClass(callInfo, &SetIteratorObject::class_);
- case InlinableNative::IntrinsicIsStringIterator:
- return inlineHasClass(callInfo, &StringIteratorObject::class_);
+ case InlinableNative::IntrinsicGuardToArrayIterator:
+ return inlineGuardToClass(callInfo, &ArrayIteratorObject::class_);
+ case InlinableNative::IntrinsicGuardToMapIterator:
+ return inlineGuardToClass(callInfo, &MapIteratorObject::class_);
+ case InlinableNative::IntrinsicGuardToSetIterator:
+ return inlineGuardToClass(callInfo, &SetIteratorObject::class_);
+ case InlinableNative::IntrinsicGuardToStringIterator:
+ return inlineGuardToClass(callInfo, &StringIteratorObject::class_);
case InlinableNative::IntrinsicDefineDataProperty:
return inlineDefineDataProperty(callInfo);
case InlinableNative::IntrinsicObjectHasPrototype:
return inlineObjectHasPrototype(callInfo);
// Map intrinsics.
+ case InlinableNative::IntrinsicGuardToMapObject:
+ return inlineGuardToClass(callInfo, &MapObject::class_);
case InlinableNative::IntrinsicGetNextMapEntryForIterator:
return inlineGetNextEntryForIterator(callInfo, MGetNextEntryForIterator::Map);
// Set intrinsics.
+ case InlinableNative::IntrinsicGuardToSetObject:
+ return inlineGuardToClass(callInfo, &SetObject::class_);
case InlinableNative::IntrinsicGetNextSetEntryForIterator:
return inlineGetNextEntryForIterator(callInfo, MGetNextEntryForIterator::Set);
@@ -2218,6 +2222,37 @@ IonBuilder::inlineHasClass(CallInfo& callInfo,
}
IonBuilder::InliningStatus
+IonBuilder::inlineGuardToClass(CallInfo& callInfo, const Class* clasp)
+{
+ MOZ_ASSERT(!callInfo.constructing());
+ MOZ_ASSERT(callInfo.argc() == 1);
+
+ if (callInfo.getArg(0)->type() != MIRType::Object)
+ return InliningStatus_NotInlined;
+
+ if (getInlineReturnType() != MIRType::ObjectOrNull &&
+ getInlineReturnType() != MIRType::Object)
+ {
+ return InliningStatus_NotInlined;
+ }
+
+ TemporaryTypeSet* types = callInfo.getArg(0)->resultTypeSet();
+ const Class* knownClass = types ? types->getKnownClass(constraints()) : nullptr;
+
+ if (knownClass && knownClass == clasp) {
+ current->push(callInfo.getArg(0));
+ } else {
+ MGuardToClass* guardToClass = MGuardToClass::New(alloc(), callInfo.getArg(0),
+ clasp, getInlineReturnType());
+ current->add(guardToClass);
+ current->push(guardToClass);
+ }
+
+ callInfo.setImplicitlyUsedUnchecked();
+ return InliningStatus_Inlined;
+}
+
+IonBuilder::InliningStatus
IonBuilder::inlineGetNextEntryForIterator(CallInfo& callInfo, MGetNextEntryForIterator::Mode mode)
{
if (callInfo.argc() != 2 || callInfo.constructing()) {
diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h
index 2de91e2df..6ec05af76 100644
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -13192,6 +13192,48 @@ class MHasClass
}
};
+class MGuardToClass
+ : public MUnaryInstruction,
+ public SingleObjectPolicy::Data
+{
+ const Class* class_;
+
+ MGuardToClass(MDefinition* object, const Class* clasp, MIRType resultType)
+ : MUnaryInstruction(object)
+ , class_(clasp)
+ {
+ MOZ_ASSERT(object->type() == MIRType::Object ||
+ (object->type() == MIRType::Value && object->mightBeType(MIRType::Object)));
+ MOZ_ASSERT(resultType == MIRType::Object || resultType == MIRType::ObjectOrNull);
+ setResultType(resultType);
+ setMovable();
+ if (resultType == MIRType::Object) {
+ // We will bail out if the class type is incorrect,
+ // so we need to ensure we don't eliminate this instruction
+ setGuard();
+ }
+ }
+
+ public:
+ INSTRUCTION_HEADER(GuardToClass)
+ TRIVIAL_NEW_WRAPPERS
+ NAMED_OPERANDS((0, object))
+
+ const Class* getClass() const {
+ return class_;
+ }
+ AliasSet getAliasSet() const override {
+ return AliasSet::None();
+ }
+ bool congruentTo(const MDefinition* ins) const override {
+ if (!ins->isGuardToClass())
+ return false;
+ if (getClass() != ins->toGuardToClass()->getClass())
+ return false;
+ return congruentIfOperandsEqual(ins);
+ }
+};
+
class MCheckReturn
: public MBinaryInstruction,
public BoxInputsPolicy::Data
diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h
index bb2ab8190..fddc1e637 100644
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -272,6 +272,7 @@ namespace jit {
_(IsCallable) \
_(IsObject) \
_(HasClass) \
+ _(GuardToClass) \
_(CopySign) \
_(Rotate) \
_(NewDerivedTypedObject) \
diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp
index f633b9b7b..9dbbe7624 100644
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -2214,6 +2214,12 @@ MacroAssembler::finish()
}
MacroAssemblerSpecific::finish();
+
+ MOZ_RELEASE_ASSERT(size() <= MaxCodeBytesPerProcess,
+ "AssemblerBuffer should ensure we don't exceed MaxCodeBytesPerProcess");
+
+ if (bytesNeeded() > MaxCodeBytesPerProcess)
+ setOOM();
}
void
diff --git a/js/src/jit/ProcessExecutableMemory.cpp b/js/src/jit/ProcessExecutableMemory.cpp
index 71c2ab0dc..301541541 100644
--- a/js/src/jit/ProcessExecutableMemory.cpp
+++ b/js/src/jit/ProcessExecutableMemory.cpp
@@ -385,14 +385,6 @@ class PageBitSet
#endif
};
-// Limit on the number of bytes of executable memory to prevent JIT spraying
-// attacks.
-#if JS_BITS_PER_WORD == 32
-static const size_t MaxCodeBytesPerProcess = 128 * 1024 * 1024;
-#else
-static const size_t MaxCodeBytesPerProcess = 1 * 1024 * 1024 * 1024;
-#endif
-
// Per-process executable memory allocator. It reserves a block of memory of
// MaxCodeBytesPerProcess bytes, then allocates/deallocates pages from that.
//
diff --git a/js/src/jit/ProcessExecutableMemory.h b/js/src/jit/ProcessExecutableMemory.h
index 078ce7cb7..a0e2fab98 100644
--- a/js/src/jit/ProcessExecutableMemory.h
+++ b/js/src/jit/ProcessExecutableMemory.h
@@ -17,6 +17,14 @@ namespace jit {
// alignment though.
static const size_t ExecutableCodePageSize = 64 * 1024;
+// Limit on the number of bytes of executable memory to prevent JIT spraying
+// attacks.
+#if JS_BITS_PER_WORD == 32
+static const size_t MaxCodeBytesPerProcess = 128 * 1024 * 1024;
+#else
+static const size_t MaxCodeBytesPerProcess = 1 * 1024 * 1024 * 1024;
+#endif
+
enum class ProtectionSetting {
Protected, // Not readable, writable, or executable.
Writable,
diff --git a/js/src/jit/RegisterSets.h b/js/src/jit/RegisterSets.h
index 0a4045dd7..08ae53f16 100644
--- a/js/src/jit/RegisterSets.h
+++ b/js/src/jit/RegisterSets.h
@@ -226,13 +226,13 @@ class ConstantOrRegister
// Space to hold either a Value or a TypedOrValueRegister.
union U {
- Value constant;
+ JS::UninitializedValue constant;
TypedOrValueRegister reg;
} data;
- const Value& dataValue() const {
+ Value dataValue() const {
MOZ_ASSERT(constant());
- return data.constant;
+ return data.constant.asValueRef();
}
void setDataValue(const Value& value) {
MOZ_ASSERT(constant());
@@ -268,7 +268,7 @@ class ConstantOrRegister
return constant_;
}
- const Value& value() const {
+ Value value() const {
return dataValue();
}
diff --git a/js/src/jit/RematerializedFrame.cpp b/js/src/jit/RematerializedFrame.cpp
index cb324220c..32fad1267 100644
--- a/js/src/jit/RematerializedFrame.cpp
+++ b/js/src/jit/RematerializedFrame.cpp
@@ -61,9 +61,17 @@ RematerializedFrame::New(JSContext* cx, uint8_t* top, InlineFrameIterator& iter,
{
unsigned numFormals = iter.isFunctionFrame() ? iter.calleeTemplate()->nargs() : 0;
unsigned argSlots = Max(numFormals, iter.numActualArgs());
- size_t numBytes = sizeof(RematerializedFrame) +
- (argSlots + iter.script()->nfixed()) * sizeof(Value) -
- sizeof(Value); // 1 Value included in sizeof(RematerializedFrame)
+ unsigned extraSlots = argSlots + iter.script()->nfixed();
+
+ // One Value slot is included in sizeof(RematerializedFrame), so we can
+ // reduce the extra slot count by one. However, if there are zero slot
+ // allocations total, then reducing the slots by one will lead to
+ // the memory allocation being smaller than sizeof(RematerializedFrame).
+ if (extraSlots > 0)
+ extraSlots -= 1;
+
+ size_t numBytes = sizeof(RematerializedFrame) + (extraSlots * sizeof(Value));
+ MOZ_ASSERT(numBytes >= sizeof(RematerializedFrame));
void* buf = cx->pod_calloc<uint8_t>(numBytes);
if (!buf)
diff --git a/js/src/jit/shared/IonAssemblerBuffer.h b/js/src/jit/shared/IonAssemblerBuffer.h
index cc20e26d2..3a6552696 100644
--- a/js/src/jit/shared/IonAssemblerBuffer.h
+++ b/js/src/jit/shared/IonAssemblerBuffer.h
@@ -181,6 +181,10 @@ class AssemblerBuffer
protected:
virtual Slice* newSlice(LifoAlloc& a) {
+ if (size() > MaxCodeBytesPerProcess - sizeof(Slice)) {
+ fail_oom();
+ return nullptr;
+ }
Slice* tmp = static_cast<Slice*>(a.alloc(sizeof(Slice)));
if (!tmp) {
fail_oom();
diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h
index 9dcb527c5..f4adcc63c 100644
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -7867,6 +7867,29 @@ class LHasClass : public LInstructionHelper<1, 1, 0>
}
};
+class LGuardToClass : public LInstructionHelper<1, 1, 1>
+{
+ public:
+ LIR_HEADER(GuardToClass);
+ explicit LGuardToClass(const LAllocation& lhs, const LDefinition& temp)
+ {
+ setOperand(0, lhs);
+ setTemp(0, temp);
+ }
+
+ const LAllocation* lhs() {
+ return getOperand(0);
+ }
+
+ const LDefinition* temp() {
+ return getTemp(0);
+ }
+
+ MGuardToClass* mir() const {
+ return mir_->toGuardToClass();
+ }
+};
+
template<size_t Defs, size_t Ops>
class LWasmSelectBase : public LInstructionHelper<Defs, Ops, 0>
{
diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h
index 3eea1b449..fe2ab5ea3 100644
--- a/js/src/jit/shared/LOpcodes-shared.h
+++ b/js/src/jit/shared/LOpcodes-shared.h
@@ -386,6 +386,7 @@
_(IsObject) \
_(IsObjectAndBranch) \
_(HasClass) \
+ _(GuardToClass) \
_(RecompileCheck) \
_(MemoryBarrier) \
_(AssertRangeI) \
diff --git a/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h
index 8cb557784..fe678fc7d 100644
--- a/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h
+++ b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h
@@ -68,6 +68,33 @@ namespace js {
namespace jit {
+ // AllocPolicy for AssemblerBuffer. OOMs when trying to allocate more than
+ // MaxCodeBytesPerProcess bytes. Use private inheritance to make sure we
+ // explicitly have to expose SystemAllocPolicy methods.
+ class AssemblerBufferAllocPolicy : private SystemAllocPolicy
+ {
+ public:
+ using SystemAllocPolicy::checkSimulatedOOM;
+ using SystemAllocPolicy::reportAllocOverflow;
+ using SystemAllocPolicy::free_;
+
+ template <typename T> T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
+ static_assert(sizeof(T) == 1,
+ "AssemblerBufferAllocPolicy should only be used with byte vectors");
+ MOZ_ASSERT(oldSize <= MaxCodeBytesPerProcess);
+ if (MOZ_UNLIKELY(newSize > MaxCodeBytesPerProcess))
+ return nullptr;
+ return SystemAllocPolicy::pod_realloc<T>(p, oldSize, newSize);
+ }
+ template <typename T> T* pod_malloc(size_t numElems) {
+ static_assert(sizeof(T) == 1,
+ "AssemblerBufferAllocPolicy should only be used with byte vectors");
+ if (MOZ_UNLIKELY(numElems > MaxCodeBytesPerProcess))
+ return nullptr;
+ return SystemAllocPolicy::pod_malloc<T>(numElems);
+ }
+ };
+
class AssemblerBuffer
{
template<size_t size, typename T>
@@ -93,6 +120,9 @@ namespace jit {
void ensureSpace(size_t space)
{
+ // This should only be called with small |space| values to ensure
+ // we don't overflow below.
+ MOZ_ASSERT(space <= 16);
if (MOZ_UNLIKELY(!m_buffer.reserve(m_buffer.length() + space)))
oomDetected();
}
@@ -168,7 +198,7 @@ namespace jit {
m_buffer.clear();
}
- PageProtectingVector<unsigned char, 256, SystemAllocPolicy> m_buffer;
+ PageProtectingVector<unsigned char, 256, AssemblerBufferAllocPolicy> m_buffer;
bool m_oom;
};