Commit 938d1e03 authored by Kenton Varda's avatar Kenton Varda

Completely replace memset() and memcpy() with zeroMemory() and copyMemory().

parent e2cbc1b5
...@@ -358,6 +358,15 @@ struct WireHelpers { ...@@ -358,6 +358,15 @@ struct WireHelpers {
memset(ptr, 0, unguard(count * BYTES_PER_POINTER / BYTES)); memset(ptr, 0, unguard(count * BYTES_PER_POINTER / BYTES));
} }
static KJ_ALWAYS_INLINE(void zeroMemory(WirePointer* ptr)) {
memset(ptr, 0, sizeof(*ptr));
}
template <typename T>
static KJ_ALWAYS_INLINE(void zeroMemory(kj::ArrayPtr<T> array)) {
memset(array.begin(), 0, array.size() * sizeof(array[0]));
}
static KJ_ALWAYS_INLINE(void copyMemory(byte* to, const byte* from, ByteCount32 count)) { static KJ_ALWAYS_INLINE(void copyMemory(byte* to, const byte* from, ByteCount32 count)) {
memcpy(to, from, unguard(count / BYTES)); memcpy(to, from, unguard(count / BYTES));
} }
...@@ -371,6 +380,24 @@ struct WireHelpers { ...@@ -371,6 +380,24 @@ struct WireHelpers {
memcpy(to, from, unguard(count * BYTES_PER_POINTER / BYTES)); memcpy(to, from, unguard(count * BYTES_PER_POINTER / BYTES));
} }
template <typename T>
static KJ_ALWAYS_INLINE(void copyMemory(T* to, const T* from)) {
memcpy(to, from, sizeof(*from));
}
// TODO(cleanup): Turn these into a .copyTo() method of ArrayPtr?
template <typename T>
static KJ_ALWAYS_INLINE(void copyMemory(T* to, kj::ArrayPtr<T> from)) {
memcpy(to, from.begin(), from.size() * sizeof(from[0]));
}
template <typename T>
static KJ_ALWAYS_INLINE(void copyMemory(T* to, kj::ArrayPtr<const T> from)) {
memcpy(to, from.begin(), from.size() * sizeof(from[0]));
}
static KJ_ALWAYS_INLINE(void copyMemory(char* to, kj::StringPtr from)) {
memcpy(to, from.begin(), from.size() * sizeof(from[0]));
}
static KJ_ALWAYS_INLINE(bool boundsCheck( static KJ_ALWAYS_INLINE(bool boundsCheck(
SegmentReader* segment, const word* start, const word* end)) { SegmentReader* segment, const word* start, const word* end)) {
// If segment is null, this is an unchecked message, so we don't do bounds checks. // If segment is null, this is an unchecked message, so we don't do bounds checks.
...@@ -564,7 +591,7 @@ struct WireHelpers { ...@@ -564,7 +591,7 @@ struct WireHelpers {
zeroMemory(pad, G(2) * POINTERS); zeroMemory(pad, G(2) * POINTERS);
} else { } else {
zeroObject(segment, capTable, pad); zeroObject(segment, capTable, pad);
zeroMemory(pad, ONE * POINTERS); zeroMemory(pad);
} }
} }
break; break;
...@@ -675,11 +702,17 @@ struct WireHelpers { ...@@ -675,11 +702,17 @@ struct WireHelpers {
if (ref->kind() == WirePointer::FAR) { if (ref->kind() == WirePointer::FAR) {
SegmentBuilder* padSegment = segment->getArena()->getSegment(ref->farRef.segmentId.get()); SegmentBuilder* padSegment = segment->getArena()->getSegment(ref->farRef.segmentId.get());
if (padSegment->isWritable()) { // Don't zero external data. if (padSegment->isWritable()) { // Don't zero external data.
word* pad = padSegment->getPtrUnchecked(ref->farPositionInSegment()); WirePointer* pad = reinterpret_cast<WirePointer*>(
memset(pad, 0, sizeof(WirePointer) * (1 + ref->isDoubleFar())); padSegment->getPtrUnchecked(ref->farPositionInSegment()));
if (ref->isDoubleFar()) {
zeroMemory(pad, G(2) * POINTERS);
} else {
zeroMemory(pad);
}
} }
} }
memset(ref, 0, sizeof(*ref));
zeroMemory(ref);
} }
...@@ -843,7 +876,7 @@ struct WireHelpers { ...@@ -843,7 +876,7 @@ struct WireHelpers {
switch (src->kind()) { switch (src->kind()) {
case WirePointer::STRUCT: { case WirePointer::STRUCT: {
if (src->isNull()) { if (src->isNull()) {
memset(dst, 0, sizeof(WirePointer)); zeroMemory(dst);
return nullptr; return nullptr;
} else { } else {
const word* srcPtr = src->target(); const word* srcPtr = src->target();
...@@ -904,7 +937,7 @@ struct WireHelpers { ...@@ -904,7 +937,7 @@ struct WireHelpers {
dst->listRef.setInlineComposite(src->listRef.inlineCompositeWordCount()); dst->listRef.setInlineComposite(src->listRef.inlineCompositeWordCount());
const WirePointer* srcTag = reinterpret_cast<const WirePointer*>(srcPtr); const WirePointer* srcTag = reinterpret_cast<const WirePointer*>(srcPtr);
memcpy(dstPtr, srcTag, sizeof(WirePointer)); copyMemory(reinterpret_cast<WirePointer*>(dstPtr), srcTag);
const word* srcElement = srcPtr + POINTER_SIZE_IN_WORDS; const word* srcElement = srcPtr + POINTER_SIZE_IN_WORDS;
word* dstElement = dstPtr + POINTER_SIZE_IN_WORDS; word* dstElement = dstPtr + POINTER_SIZE_IN_WORDS;
...@@ -948,12 +981,12 @@ struct WireHelpers { ...@@ -948,12 +981,12 @@ struct WireHelpers {
// We expect the caller to ensure the target is already null so won't leak. // We expect the caller to ensure the target is already null so won't leak.
if (src->isNull()) { if (src->isNull()) {
memset(dst, 0, sizeof(WirePointer)); zeroMemory(dst);
} else if (src->isPositional()) { } else if (src->isPositional()) {
transferPointer(dstSegment, dst, srcSegment, src, src->target()); transferPointer(dstSegment, dst, srcSegment, src, src->target());
} else { } else {
// Far and other pointers are position-independent, so we can just copy. // Far and other pointers are position-independent, so we can just copy.
memcpy(dst, src, sizeof(WirePointer)); copyMemory(dst, src);
} }
} }
...@@ -973,7 +1006,7 @@ struct WireHelpers { ...@@ -973,7 +1006,7 @@ struct WireHelpers {
} }
// We can just copy the upper 32 bits. (Use memcpy() to comply with aliasing rules.) // We can just copy the upper 32 bits. (Use memcpy() to comply with aliasing rules.)
memcpy(&dst->upper32Bits, &srcTag->upper32Bits, sizeof(srcTag->upper32Bits)); copyMemory(&dst->upper32Bits, &srcTag->upper32Bits);
} else { } else {
// Need to create a far pointer. Try to allocate it in the same segment as the source, so // Need to create a far pointer. Try to allocate it in the same segment as the source, so
// that it doesn't need to be a double-far. // that it doesn't need to be a double-far.
...@@ -990,14 +1023,14 @@ struct WireHelpers { ...@@ -990,14 +1023,14 @@ struct WireHelpers {
landingPad[0].farRef.segmentId.set(srcSegment->getSegmentId()); landingPad[0].farRef.segmentId.set(srcSegment->getSegmentId());
landingPad[1].setKindWithZeroOffset(srcTag->kind()); landingPad[1].setKindWithZeroOffset(srcTag->kind());
memcpy(&landingPad[1].upper32Bits, &srcTag->upper32Bits, sizeof(srcTag->upper32Bits)); copyMemory(&landingPad[1].upper32Bits, &srcTag->upper32Bits);
dst->setFar(true, farSegment->getOffsetTo(reinterpret_cast<word*>(landingPad))); dst->setFar(true, farSegment->getOffsetTo(reinterpret_cast<word*>(landingPad)));
dst->farRef.set(farSegment->getSegmentId()); dst->farRef.set(farSegment->getSegmentId());
} else { } else {
// Simple landing pad is just a pointer. // Simple landing pad is just a pointer.
landingPad->setKindAndTarget(srcTag->kind(), srcPtr, srcSegment); landingPad->setKindAndTarget(srcTag->kind(), srcPtr, srcSegment);
memcpy(&landingPad->upper32Bits, &srcTag->upper32Bits, sizeof(srcTag->upper32Bits)); copyMemory(&landingPad->upper32Bits, &srcTag->upper32Bits);
dst->setFar(false, srcSegment->getOffsetTo(reinterpret_cast<word*>(landingPad))); dst->setFar(false, srcSegment->getOffsetTo(reinterpret_cast<word*>(landingPad)));
dst->farRef.set(srcSegment->getSegmentId()); dst->farRef.set(srcSegment->getSegmentId());
...@@ -1549,7 +1582,7 @@ struct WireHelpers { ...@@ -1549,7 +1582,7 @@ struct WireHelpers {
[]() { KJ_FAIL_REQUIRE("text blob too big"); }) * BYTES; []() { KJ_FAIL_REQUIRE("text blob too big"); }) * BYTES;
auto allocation = initTextPointer(ref, segment, capTable, size, orphanArena); auto allocation = initTextPointer(ref, segment, capTable, size, orphanArena);
memcpy(allocation.value.begin(), value.begin(), value.size()); copyMemory(allocation.value.begin(), value);
return allocation; return allocation;
} }
...@@ -1612,7 +1645,7 @@ struct WireHelpers { ...@@ -1612,7 +1645,7 @@ struct WireHelpers {
[]() { KJ_FAIL_REQUIRE("text blob too big"); }) * BYTES; []() { KJ_FAIL_REQUIRE("text blob too big"); }) * BYTES;
auto allocation = initDataPointer(ref, segment, capTable, size, orphanArena); auto allocation = initDataPointer(ref, segment, capTable, size, orphanArena);
memcpy(allocation.value.begin(), value.begin(), value.size()); copyMemory(allocation.value.begin(), value);
return allocation; return allocation;
} }
...@@ -1728,7 +1761,7 @@ struct WireHelpers { ...@@ -1728,7 +1761,7 @@ struct WireHelpers {
zeroObject(segment, capTable, ref); zeroObject(segment, capTable, ref);
} }
if (cap->isNull()) { if (cap->isNull()) {
memset(ref, 0, sizeof(*ref)); zeroMemory(ref);
} else { } else {
ref->setCap(capTable->injectCap(kj::mv(cap))); ref->setCap(capTable->injectCap(kj::mv(cap)));
} }
...@@ -1862,7 +1895,7 @@ struct WireHelpers { ...@@ -1862,7 +1895,7 @@ struct WireHelpers {
useDefault: useDefault:
if (!dst->isNull()) { if (!dst->isNull()) {
zeroObject(dstSegment, dstCapTable, dst); zeroObject(dstSegment, dstCapTable, dst);
memset(dst, 0, sizeof(*dst)); zeroMemory(dst);
} }
return { dstSegment, nullptr }; return { dstSegment, nullptr };
} }
...@@ -2012,16 +2045,16 @@ struct WireHelpers { ...@@ -2012,16 +2045,16 @@ struct WireHelpers {
if (value == nullptr) { if (value == nullptr) {
// Set null. // Set null.
memset(ref, 0, sizeof(*ref)); zeroMemory(ref);
} else if (value.tagAsPtr()->isPositional()) { } else if (value.tagAsPtr()->isPositional()) {
WireHelpers::transferPointer(segment, ref, value.segment, value.tagAsPtr(), value.location); WireHelpers::transferPointer(segment, ref, value.segment, value.tagAsPtr(), value.location);
} else { } else {
// FAR and OTHER pointers are position-independent, so we can just copy. // FAR and OTHER pointers are position-independent, so we can just copy.
memcpy(ref, value.tagAsPtr(), sizeof(WirePointer)); copyMemory(ref, value.tagAsPtr());
} }
// Take ownership away from the OrphanBuilder. // Take ownership away from the OrphanBuilder.
memset(value.tagAsPtr(), 0, sizeof(WirePointer)); zeroMemory(value.tagAsPtr());
value.location = nullptr; value.location = nullptr;
value.segment = nullptr; value.segment = nullptr;
} }
...@@ -2047,7 +2080,7 @@ struct WireHelpers { ...@@ -2047,7 +2080,7 @@ struct WireHelpers {
} }
// Zero out the pointer that was disowned. // Zero out the pointer that was disowned.
memset(ref, 0, sizeof(*ref)); zeroMemory(ref);
return result; return result;
} }
...@@ -2509,7 +2542,7 @@ OrphanBuilder PointerBuilder::disown() { ...@@ -2509,7 +2542,7 @@ OrphanBuilder PointerBuilder::disown() {
void PointerBuilder::clear() { void PointerBuilder::clear() {
WireHelpers::zeroObject(segment, capTable, pointer); WireHelpers::zeroObject(segment, capTable, pointer);
memset(pointer, 0, sizeof(WirePointer)); WireHelpers::zeroMemory(pointer);
} }
PointerType PointerBuilder::getPointerType() const { PointerType PointerBuilder::getPointerType() const {
...@@ -2537,17 +2570,17 @@ PointerType PointerBuilder::getPointerType() const { ...@@ -2537,17 +2570,17 @@ PointerType PointerBuilder::getPointerType() const {
void PointerBuilder::transferFrom(PointerBuilder other) { void PointerBuilder::transferFrom(PointerBuilder other) {
if (!pointer->isNull()) { if (!pointer->isNull()) {
WireHelpers::zeroObject(segment, capTable, pointer); WireHelpers::zeroObject(segment, capTable, pointer);
memset(pointer, 0, sizeof(*pointer)); WireHelpers::zeroMemory(pointer);
} }
WireHelpers::transferPointer(segment, pointer, other.segment, other.pointer); WireHelpers::transferPointer(segment, pointer, other.segment, other.pointer);
memset(other.pointer, 0, sizeof(*other.pointer)); WireHelpers::zeroMemory(other.pointer);
} }
void PointerBuilder::copyFrom(PointerReader other, bool canonical) { void PointerBuilder::copyFrom(PointerReader other, bool canonical) {
if (other.pointer == nullptr) { if (other.pointer == nullptr) {
if (!pointer->isNull()) { if (!pointer->isNull()) {
WireHelpers::zeroObject(segment, capTable, pointer); WireHelpers::zeroObject(segment, capTable, pointer);
memset(pointer, 0, sizeof(*pointer)); WireHelpers::zeroMemory(pointer);
} }
} else { } else {
WireHelpers::copyPointer(segment, capTable, pointer, WireHelpers::copyPointer(segment, capTable, pointer,
...@@ -2847,13 +2880,13 @@ MessageSizeCounts StructReader::totalSize() const { ...@@ -2847,13 +2880,13 @@ MessageSizeCounts StructReader::totalSize() const {
kj::Array<word> StructReader::canonicalize() { kj::Array<word> StructReader::canonicalize() {
WordCount size = totalSize().wordCount + POINTER_SIZE_IN_WORDS; WordCount size = totalSize().wordCount + POINTER_SIZE_IN_WORDS;
kj::Array<word> backing = kj::heapArray<word>(size / WORDS); kj::Array<word> backing = kj::heapArray<word>(size / WORDS);
memset(backing.begin(), 0, backing.asBytes().size()); WireHelpers::zeroMemory(backing.begin());
FlatMessageBuilder builder(backing); FlatMessageBuilder builder(backing);
_::PointerHelpers<AnyPointer>::getInternalBuilder(builder.initRoot<AnyPointer>()).setStruct(*this, true); _::PointerHelpers<AnyPointer>::getInternalBuilder(builder.initRoot<AnyPointer>()).setStruct(*this, true);
KJ_ASSERT(builder.isCanonical()); KJ_ASSERT(builder.isCanonical());
auto output = builder.getSegmentsForOutput()[0]; auto output = builder.getSegmentsForOutput()[0];
kj::Array<word> trunc = kj::heapArray<word>(output.size()); kj::Array<word> trunc = kj::heapArray<word>(output.size());
memcpy(trunc.begin(), output.begin(), output.asBytes().size()); WireHelpers::copyMemory(trunc.begin(), output);
return trunc; return trunc;
} }
...@@ -3322,8 +3355,8 @@ OrphanBuilder OrphanBuilder::concat( ...@@ -3322,8 +3355,8 @@ OrphanBuilder OrphanBuilder::concat(
auto step = builder.step / BITS_PER_BYTE; auto step = builder.step / BITS_PER_BYTE;
for (auto& list: lists) { for (auto& list: lists) {
auto count = step * list.size(); auto count = step * list.size();
memcpy(target, list.ptr, count / BYTES); WireHelpers::copyMemory(target, list.ptr, count);
target += count / BYTES; target += count;
} }
break; break;
} }
...@@ -3443,6 +3476,8 @@ Data::Reader OrphanBuilder::asDataReader() const { ...@@ -3443,6 +3476,8 @@ Data::Reader OrphanBuilder::asDataReader() const {
} }
bool OrphanBuilder::truncate(ElementCount size, bool isText) { bool OrphanBuilder::truncate(ElementCount size, bool isText) {
// TODO(now): Method may have been damaged by merge conflicts.
WirePointer* ref = tagAsPtr(); WirePointer* ref = tagAsPtr();
SegmentBuilder* segment = this->segment; SegmentBuilder* segment = this->segment;
...@@ -3491,7 +3526,7 @@ bool OrphanBuilder::truncate(ElementCount size, bool isText) { ...@@ -3491,7 +3526,7 @@ bool OrphanBuilder::truncate(ElementCount size, bool isText) {
// with us. // with us.
word* expectedEnd = target + oldSize * (elementWordCount / ELEMENTS); word* expectedEnd = target + oldSize * (elementWordCount / ELEMENTS);
KJ_ASSERT(newEndWord >= expectedEnd); KJ_ASSERT(newEndWord >= expectedEnd);
memset(expectedEnd, 0, (newEndWord - expectedEnd) * sizeof(word)); WireHelpers::zeroMemory(expectedEnd, newEndWord - expectedEnd);
tag->setKindAndInlineCompositeListElementCount(WirePointer::STRUCT, size); tag->setKindAndInlineCompositeListElementCount(WirePointer::STRUCT, size);
} else { } else {
if (segment->tryExtend(oldEndWord, newEndWord)) { if (segment->tryExtend(oldEndWord, newEndWord)) {
...@@ -3558,7 +3593,7 @@ bool OrphanBuilder::truncate(ElementCount size, bool isText) { ...@@ -3558,7 +3593,7 @@ bool OrphanBuilder::truncate(ElementCount size, bool isText) {
byte* newEndByte = begin + WireHelpers::roundBitsUpToBytes(size * step) - isText; byte* newEndByte = begin + WireHelpers::roundBitsUpToBytes(size * step) - isText;
byte* oldEndByte = reinterpret_cast<byte*>(oldEndWord); byte* oldEndByte = reinterpret_cast<byte*>(oldEndWord);
memset(newEndByte, 0, oldEndByte - newEndByte); WireHelpers::zeroMemory(newEndByte, intervalLength(newEndByte, oldEndByte));
ref->listRef.set(elementSize, size); ref->listRef.set(elementSize, size);
segment->tryTruncate(oldEndWord, newEndWord); segment->tryTruncate(oldEndWord, newEndWord);
} else { } else {
...@@ -3571,7 +3606,7 @@ bool OrphanBuilder::truncate(ElementCount size, bool isText) { ...@@ -3571,7 +3606,7 @@ bool OrphanBuilder::truncate(ElementCount size, bool isText) {
OrphanBuilder replacement = initList(segment->getArena(), capTable, size, elementSize); OrphanBuilder replacement = initList(segment->getArena(), capTable, size, elementSize);
ListBuilder newList = replacement.asList(elementSize); ListBuilder newList = replacement.asList(elementSize);
auto words = WireHelpers::roundBitsUpToWords(dataBitsPerElement(elementSize) * oldSize); auto words = WireHelpers::roundBitsUpToWords(dataBitsPerElement(elementSize) * oldSize);
memcpy(newList.ptr, target, words * BYTES_PER_WORD / BYTES); WireHelpers::copyMemory(newList.ptr, target, words);
*this = kj::mv(replacement); *this = kj::mv(replacement);
} }
} }
...@@ -3608,7 +3643,7 @@ void OrphanBuilder::euthanize() { ...@@ -3608,7 +3643,7 @@ void OrphanBuilder::euthanize() {
WireHelpers::zeroObject(segment, capTable, tagAsPtr()); WireHelpers::zeroObject(segment, capTable, tagAsPtr());
} }
memset(&tag, 0, sizeof(tag)); WireHelpers::zeroMemory(&tag, ONE * WORDS);
segment = nullptr; segment = nullptr;
location = nullptr; location = nullptr;
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment