From 24b0e91d8096f84a114f662e3eb42c83d0d3878d Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Mon, 9 Jul 2018 03:35:34 +0200 Subject: Move buffers between V8 and native * send()/recv() now operate on TypedArrays rather than ArrayBuffers. * Remove a copy (through ArrayBuffer.slice()) from the send path. * Remove a copy (through v8::ArrayBuffer::New()) from the return path. * After moving a buffer from JS to native, the ArrayBuffer object and it's views are made inaccessible ('neutered'). * `struct deno_buf` now holds two [ptr, length] tuples, one for the actual memory allocation, and one for the logical data contained therein. This is necessary because flatbuffers fills it's buffer bottom-up, so the serialized blob doesn't start at beginning of the buffer, but somewhere in the middle. --- src/flatbuffer_builder.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/flatbuffer_builder.h (limited to 'src/flatbuffer_builder.h') diff --git a/src/flatbuffer_builder.h b/src/flatbuffer_builder.h new file mode 100644 index 000000000..1bc973afe --- /dev/null +++ b/src/flatbuffer_builder.h @@ -0,0 +1,64 @@ +// Copyright 2018 Bert Belder +// All rights reserved. MIT License. +#ifndef FLATBUFFER_BUILDER_H_ +#define FLATBUFFER_BUILDER_H_ + +#include +#include +#include + +#include "deno.h" +#include "flatbuffers/flatbuffers.h" + +namespace deno { + +// Wrap the default FlatBufferBuilder class, because the default one can't give +// us a pointer to the output buffer that we own. Nominally, +// FlatBufferBuilder::Release() should do that, but it returns some +// smart-pointer-like object (DetachedBuffer) that frees the buffer when it goes +// out of scope. +// +// This wrapper adds the `ExportBuf` method that returns a deno_buf, which +// is really not owned at all -- the caller is responsible for releasing the +// allocation with free(). +// +// The alternative allocator also uses malloc()/free(), rather than +// new/delete[], so that the exported buffer can be later be converted to an +// ArrayBuffer; the (default) V8 ArrayBuffer allocator also uses free(). +class FlatBufferBuilder : public flatbuffers::FlatBufferBuilder { + static const size_t kDefaultInitialSize = 1024; + + class Allocator : public flatbuffers::Allocator { + uint8_t* keep_alloc_ptr_ = nullptr; + uint8_t* last_alloc_ptr_ = nullptr; + size_t last_alloc_len_ = 0; + + public: + deno_buf GetAndKeepBuf(uint8_t* data_ptr, size_t data_len); + + protected: + virtual uint8_t* allocate(size_t size); + virtual void deallocate(uint8_t* ptr, size_t size); + }; + + Allocator allocator_; + + public: + explicit FlatBufferBuilder(size_t initial_size = kDefaultInitialSize) + : flatbuffers::FlatBufferBuilder(initial_size, &allocator_) {} + + // Export the finalized flatbuffer as a deno_buf structure. The caller takes + // ownership of the underlying memory allocation, which must be released with + // free(). + // Afer calling ExportBuf() the FlatBufferBuilder should no longer be used; + // However it can be used again once it is reset with the Reset() method. + deno_buf ExportBuf(); + + // Don't use these. + flatbuffers::DetachedBuffer Release() = delete; + flatbuffers::DetachedBuffer ReleaseBufferPointer() = delete; +}; + +} // namespace deno + +#endif // FLATBUFFER_BUILDER_H_ -- cgit v1.2.3