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.

Reply via email to