From 2902b6c753930d0c5805bb2d98483aa5afdb24f2 Mon Sep 17 00:00:00 2001 From: David Renshaw Date: Tue, 4 Nov 2014 21:53:34 -0500 Subject: [PATCH] working on WireHelpers.zeroObject --- .../java/org/capnproto/SegmentBuilder.java | 5 ++ .../main/java/org/capnproto/WireHelpers.java | 54 ++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/runtime/src/main/java/org/capnproto/SegmentBuilder.java b/runtime/src/main/java/org/capnproto/SegmentBuilder.java index 216a50c..5ac34ff 100644 --- a/runtime/src/main/java/org/capnproto/SegmentBuilder.java +++ b/runtime/src/main/java/org/capnproto/SegmentBuilder.java @@ -63,4 +63,9 @@ public final class SegmentBuilder extends SegmentReader { public final BuilderArena getArena() { return (BuilderArena)this.arena; } + + public final boolean isWritable() { + // TODO support external non-writable segments + return true; + } } diff --git a/runtime/src/main/java/org/capnproto/WireHelpers.java b/runtime/src/main/java/org/capnproto/WireHelpers.java index 446b9d1..f46334d 100644 --- a/runtime/src/main/java/org/capnproto/WireHelpers.java +++ b/runtime/src/main/java/org/capnproto/WireHelpers.java @@ -166,9 +166,54 @@ final class WireHelpers { //# about to be overwritten making the target object no longer //# reachable. - // TODO + //# We shouldn't zero out external data linked into the message. + if (!segment.isWritable()) return; + + long ref = segment.get(refOffset); + + switch (WirePointer.kind(ref)) { + case WirePointer.STRUCT: + case WirePointer.LIST: + zeroObject(segment, ref, WirePointer.target(refOffset, ref)); + break; + case WirePointer.FAR: { + segment = segment.getArena().getSegment(FarPointer.getSegmentId(ref)); + if (!segment.isWritable()) { //# Don't zero external data. + // TODO + + } + break; + } + case WirePointer.OTHER: { + } + } } + static void zeroObject(SegmentBuilder segment, long tag, int ptr) { + //# We shouldn't zero out external data linked into the message. + if (!segment.isWritable()) return; + + switch (WirePointer.kind(tag)) { + case WirePointer.STRUCT: { + int pointerSection = ptr + StructPointer.dataSize(tag); + int count = StructPointer.ptrCount(tag); + for (int ii = 0; ii < count; ++ii) { + zeroObject(segment, pointerSection + ii); + } + memset(segment.buffer, ptr * Constants.BYTES_PER_WORD, (byte)0, + StructPointer.wordSize(tag) * Constants.BYTES_PER_WORD); + break; + } + case WirePointer.LIST: { + // TODO + break; + } + case WirePointer.FAR: + throw new Error("Unexpected FAR pointer."); + case WirePointer.OTHER: + throw new Error("Unexpected OTHER pointer."); + } + } static T initStructPointer(StructBuilder.Factory factory, int refOffset, @@ -625,6 +670,13 @@ final class WireHelpers { } } + static void memset(ByteBuffer dstBuffer, int dstByteOffset, byte value, int length) { + // TODO we can probably do this faster + for (int ii = dstByteOffset; ii < dstByteOffset + length; ++ii) { + dstBuffer.put(ii, value); + } + } + static void memcpy(ByteBuffer dstBuffer, int dstByteOffset, ByteBuffer srcBuffer, int srcByteOffset, int length) { ByteBuffer dstDup = dstBuffer.duplicate(); dstDup.position(dstByteOffset);