From 449ef9f5031d36827ea4632a700894ea961ee98c Mon Sep 17 00:00:00 2001 From: David Renshaw Date: Mon, 16 Jun 2014 14:49:12 -0400 Subject: [PATCH] finish allocate --- .../main/java/org/capnproto/BuilderArena.java | 17 ++++++++++++++++- .../src/main/java/org/capnproto/FarPointer.java | 9 +++++++++ .../main/java/org/capnproto/SegmentBuilder.java | 1 + .../main/java/org/capnproto/WireHelpers.java | 15 ++++++++++++++- 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 runtime/src/main/java/org/capnproto/FarPointer.java diff --git a/runtime/src/main/java/org/capnproto/BuilderArena.java b/runtime/src/main/java/org/capnproto/BuilderArena.java index 5734725..abf8fb5 100644 --- a/runtime/src/main/java/org/capnproto/BuilderArena.java +++ b/runtime/src/main/java/org/capnproto/BuilderArena.java @@ -61,11 +61,26 @@ public final class BuilderArena implements Arena { return new AllocateResult(this.segments.get(len - 1), result); } + // allocate_owned_memory + + int size = Math.max(amount, this.nextSize); SegmentBuilder newSegment = new SegmentBuilder( - ByteBuffer.allocate(amount * Constants.BYTES_PER_WORD), + ByteBuffer.allocate(size * Constants.BYTES_PER_WORD), this); + + switch (this.allocationStrategy) { + case GROW_HEURISTICALLY: + this.nextSize += size; + break; + default: + break; + } + + // -------- + newSegment.buffer.mark(); newSegment.buffer.order(ByteOrder.LITTLE_ENDIAN); + newSegment.id = len; this.segments.add(newSegment); return new AllocateResult(newSegment, newSegment.allocate(amount)); diff --git a/runtime/src/main/java/org/capnproto/FarPointer.java b/runtime/src/main/java/org/capnproto/FarPointer.java new file mode 100644 index 0000000..65c8fa6 --- /dev/null +++ b/runtime/src/main/java/org/capnproto/FarPointer.java @@ -0,0 +1,9 @@ +package org.capnproto; + +import java.nio.ByteBuffer; + +final class FarPointer { + public static void set(ByteBuffer buffer, int offset, int segmentId) { + buffer.putInt(8 * offset + 4, segmentId); + } +} diff --git a/runtime/src/main/java/org/capnproto/SegmentBuilder.java b/runtime/src/main/java/org/capnproto/SegmentBuilder.java index 38581ff..6ae626c 100644 --- a/runtime/src/main/java/org/capnproto/SegmentBuilder.java +++ b/runtime/src/main/java/org/capnproto/SegmentBuilder.java @@ -7,6 +7,7 @@ public final class SegmentBuilder extends SegmentReader { public static final int FAILED_ALLOCATION = -1; public int pos = 0; // in words + public int id = 0; public SegmentBuilder(ByteBuffer buf, Arena arena) { super(buf, arena); diff --git a/runtime/src/main/java/org/capnproto/WireHelpers.java b/runtime/src/main/java/org/capnproto/WireHelpers.java index 594f340..9b349b6 100644 --- a/runtime/src/main/java/org/capnproto/WireHelpers.java +++ b/runtime/src/main/java/org/capnproto/WireHelpers.java @@ -36,7 +36,20 @@ final class WireHelpers { int amountPlusRef = amount + Constants.POINTER_SIZE_IN_WORDS; BuilderArena.AllocateResult allocation = segment.getArena().allocate(amountPlusRef); - throw new Error("unimplemented"); + //# Set up the original pointer to be a far pointer to + //# the new segment. + WirePointer.setKindAndTarget(segment.buffer, refOffset, WirePointer.FAR, allocation.offset); + FarPointer.set(segment.buffer, refOffset, allocation.segment.id); + + //# Initialize the landing pad to indicate that the + //# data immediately follows the pad. + int resultRefOffset = allocation.offset; + int ptr1 = allocation.offset + Constants.POINTER_SIZE_IN_WORDS; + + WirePointer.setKindAndTarget(allocation.segment.buffer, resultRefOffset, kind, + ptr1); + + return new AllocateResult(ptr1, resultRefOffset, allocation.segment); } else { WirePointer.setKindAndTarget(segment.buffer, refOffset, kind, ptr); return new AllocateResult(ptr, refOffset, segment);