This is spot on to how I understand the behavior, however I think this behavior exposes the problems I outlined. This is especially evident if you are writing in a binding in a “plugin” like environment where you are not the one to setup the Allocator for array buffers.
Your use of the internal fields to store values is exactly the “hacks” I was referring to. This seems unsafe given that if you pass around the array buffer and something else decides to use these internal fields in a different way then you will be ruined. Yes, I agree if you create an array buffer using already externalized constructor then you most likely know where the memory came from and can free it, but if you received an array buffer as an argument or used the non externalized constructor, then it would be very apt to just have access to the memory if the handle is still alive. On December 9, 2013 at 1:02:01 AM, Justin King ([email protected]) wrote: I believe I can shine some light on this. There are a few things that are not explained well by the current implementation. Feel free to correct me if I am wrong. The only difference between a non-externalized ArrayBuffer and an externalized ArrayBuffer is who is responsible for managing the underlying buffer. The underlying buffer of a non-externalized ArrayBuffer is guaranteed to be allocated by the specified ArrayBuffer::Allocator set prior to execution using V8::SetArrayBufferAllocator. What Google Chrome does (last I checked) is use the default internal fields created with each ArrayBuffer and ArrayBufferView controlled by V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT and V8_ARRAY_BUFFER_VIEW_INTERNAL_FIELD_COUNT macros respectively. Once externalized you may store the pointer to the underlying storage in one field and another pointer to the persistent storage cell within V8 to be notified when the ArrayBuffer becomes "weak". Every time you come across an ArrayBuffer you may use the shadowed method ArrayBuffer::IsExternal to check if ArrayBuffer::Externalize has been called, which implies you can access the pointer. The ArrayBuffer continues to use the same underlying storage even after calling ArrayBuffer::Externalize until ArrayBuffer::Neuter is called to remove all references to the underlying storage among the ArrayBuffer and its ArrayBufferViews. Since the embedder (you) is responsible for implementing the ArrayBuffer::Allocator V8 assumes you have a reference. The easiest way to replicate this is use a singleton class with a public method returning the singleton (I believe this is the approach used by Google Chrome). V8 also assumes that if you create a new ArrayBuffer via ArrayBufer::New(Isolate*, void*, size_t) you know how you allocated it, and thus we come back full circle to the responsibility of the implementer. There is no possible way for V8 or JavaScript to avoid using the ArrayBuffer::Allocator. Only the embedder may create a pre-externalized ArrayBuffer via ArrayBuffer::New(Isolate*, void*, size_t). Hope this helps, Justin On Sun, Dec 8, 2013 at 10:56 PM, Roman Shtylman <[email protected]> wrote: A few things are unclear to me after trying to use the ArrayBuffer api from v8 3.23.10 The first inconsistency I find is the disconnect between an initialized ArrayBuffer allocated via the globally set allocator and one that you have then externalized. It seems there is no good way to get this global allocator and thus properly know how to cleanup the ArrayBuffer::Contents once you you have them. The other difficult aspect is the inability to get the externalized contents again once you have gotten them once. This makes sense in the context of "externalization" but what I would find very useful is just access to the data pointer for the array buffer and let it continue to manage the lifetime of the memory. Allowing the array buffer to manage the lifetime has the nice benefit of using the correct allocator and re-using the memory if I have calls that want to do so; right now it is not possible to easily re-use the memory without some clever hacks. We already have a system for increasing the lifetime of a handle (persistents) so externalizing just to access the data and ensure it is not deleted too soon doesn't seem like a relevant api. tl;dr; 1. ArrayBuffer::Contents could be inconsistent with global ArrayBuffer allocator 2. No way to reuse array buffer memory since externalize can only happen once -- -- v8-users mailing list [email protected] http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out. -- Michigan Technological University Computer Network and Systems Administration Information Technology Operations Work: (906) 487-1999 Cell: (906) 282-7946 -- -- v8-users mailing list [email protected] http://groups.google.com/group/v8-users --- You received this message because you are subscribed to a topic in the Google Groups "v8-users" group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/v8-users/whHPAIhfMu8/unsubscribe. To unsubscribe from this group and all its topics, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out. -- -- v8-users mailing list [email protected] http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
