Skip to content

Commit

Permalink
gin: Make it possible to use gin array buffers when running on top of…
Browse files Browse the repository at this point in the history
… blink

This approach won't let use share an array buffer with blink, however,
it's good enough for a mojo js app.

For gin::Wrappable objects that want to interact with blink APIs, they
need to provide a custom converter to and from WebArrayBuffer(View)

BUG=none
R=abarth@chromium.org, dslomov@chromium.org, sky@chromium.org

Review URL: https://codereview.chromium.org/172133002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252190 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
jochen@chromium.org committed Feb 20, 2014
1 parent 13d954d commit 73dcce9
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 20 deletions.
29 changes: 21 additions & 8 deletions gin/array_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gin/array_buffer.h"

#include <stdlib.h>

#include "base/logging.h"
#include "gin/array_buffer.h"
#include "gin/per_isolate_data.h"

namespace gin {

namespace {

gin::WrapperInfo g_array_buffer_wrapper_info = {gin::kEmbedderNativeGin};

} // namespace

COMPILE_ASSERT(V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT == 2,
array_buffers_must_have_two_internal_fields);

static const int kBufferViewPrivateIndex = 0;

// ArrayBufferAllocator -------------------------------------------------------

void* ArrayBufferAllocator::Allocate(size_t length) {
Expand Down Expand Up @@ -72,35 +78,42 @@ class ArrayBuffer::Private : public base::RefCounted<ArrayBuffer::Private> {

v8::Persistent<v8::ArrayBuffer> array_buffer_;
scoped_refptr<Private> self_reference_;
v8::Isolate* isolate_;
void* buffer_;
size_t length_;
};

scoped_refptr<ArrayBuffer::Private> ArrayBuffer::Private::From(
v8::Isolate* isolate, v8::Handle<v8::ArrayBuffer> array) {
if (array->IsExternal()) {
CHECK_EQ(WrapperInfo::From(v8::Handle<v8::Object>::Cast(array)),
&g_array_buffer_wrapper_info)
<< "Cannot mix blink and gin ArrayBuffers";
return make_scoped_refptr(static_cast<Private*>(
array->GetAlignedPointerFromInternalField(kBufferViewPrivateIndex)));
array->GetAlignedPointerFromInternalField(kEncodedValueIndex)));
}
return make_scoped_refptr(new Private(isolate, array));
}

ArrayBuffer::Private::Private(v8::Isolate* isolate,
v8::Handle<v8::ArrayBuffer> array)
: array_buffer_(isolate, array) {
: array_buffer_(isolate, array), isolate_(isolate) {
// Take ownership of the array buffer.
CHECK(!array->IsExternal());
v8::ArrayBuffer::Contents contents = array->Externalize();
buffer_ = contents.Data();
length_ = contents.ByteLength();

array->SetAlignedPointerInInternalField(kBufferViewPrivateIndex, this);
array->SetAlignedPointerInInternalField(kWrapperInfoIndex,
&g_array_buffer_wrapper_info);
array->SetAlignedPointerInInternalField(kEncodedValueIndex, this);

self_reference_ = this; // Cleared in WeakCallback.
array_buffer_.SetWeak(this, WeakCallback);
}

ArrayBuffer::Private::~Private() {
ArrayBufferAllocator::SharedInstance()->Free(buffer_, length_);
PerIsolateData::From(isolate_)->allocator()->Free(buffer_, length_);
}

void ArrayBuffer::Private::WeakCallback(
Expand Down
15 changes: 11 additions & 4 deletions gin/isolate_holder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,21 @@ IsolateHolder::IsolateHolder()
constraints.ConfigureDefaults(base::SysInfo::AmountOfPhysicalMemory(),
base::SysInfo::NumberOfProcessors());
v8::SetResourceConstraints(isolate_, &constraints);
Init();
Init(ArrayBufferAllocator::SharedInstance());
}

IsolateHolder::IsolateHolder(v8::Isolate* isolate)
: isolate_owner_(false),
isolate_(isolate) {
EnsureV8Initialized(false);
Init();
Init(NULL);
}

IsolateHolder::IsolateHolder(v8::Isolate* isolate,
v8::ArrayBuffer::Allocator* allocator)
: isolate_owner_(false), isolate_(isolate) {
EnsureV8Initialized(false);
Init(allocator);
}

IsolateHolder::~IsolateHolder() {
Expand All @@ -69,10 +76,10 @@ IsolateHolder::~IsolateHolder() {
isolate_->Dispose();
}

void IsolateHolder::Init() {
void IsolateHolder::Init(v8::ArrayBuffer::Allocator* allocator) {
v8::Isolate::Scope isolate_scope(isolate_);
v8::HandleScope handle_scope(isolate_);
isolate_data_.reset(new PerIsolateData(isolate_));
isolate_data_.reset(new PerIsolateData(isolate_, allocator));
}

} // namespace gin
6 changes: 4 additions & 2 deletions gin/per_isolate_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "gin/per_isolate_data.h"
#include "gin/public/gin_embedders.h"

using v8::ArrayBuffer;
using v8::Eternal;
using v8::Isolate;
using v8::Local;
Expand All @@ -14,8 +15,9 @@ using v8::ObjectTemplate;

namespace gin {

PerIsolateData::PerIsolateData(Isolate* isolate)
: isolate_(isolate) {
PerIsolateData::PerIsolateData(Isolate* isolate,
ArrayBuffer::Allocator* allocator)
: isolate_(isolate), allocator_(allocator) {
isolate_->SetData(kEmbedderNativeGin, this);
}

Expand Down
4 changes: 3 additions & 1 deletion gin/per_isolate_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace gin {
// class stores all the Gin-related data that varies per isolate.
class GIN_EXPORT PerIsolateData {
public:
explicit PerIsolateData(v8::Isolate* isolate);
PerIsolateData(v8::Isolate* isolate, v8::ArrayBuffer::Allocator* allocator);
~PerIsolateData();

static PerIsolateData* From(v8::Isolate* isolate);
Expand All @@ -39,6 +39,7 @@ class GIN_EXPORT PerIsolateData {
v8::Local<v8::FunctionTemplate> GetFunctionTemplate(WrapperInfo* info);

v8::Isolate* isolate() { return isolate_; }
v8::ArrayBuffer::Allocator* allocator() { return allocator_; }

private:
typedef std::map<
Expand All @@ -49,6 +50,7 @@ class GIN_EXPORT PerIsolateData {
// PerIsolateData doesn't actually own |isolate_|. Instead, the isolate is
// owned by the IsolateHolder, which also owns the PerIsolateData.
v8::Isolate* isolate_;
v8::ArrayBuffer::Allocator* allocator_;
ObjectTemplateMap object_templates_;
FunctionTemplateMap function_templates_;

Expand Down
10 changes: 5 additions & 5 deletions gin/public/isolate_holder.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "gin/gin_export.h"

namespace v8 {
class Isolate;
}
#include "v8/include/v8.h"

namespace gin {

Expand All @@ -30,14 +27,17 @@ class PerIsolateData;
class GIN_EXPORT IsolateHolder {
public:
IsolateHolder();
IsolateHolder(v8::Isolate* isolate, v8::ArrayBuffer::Allocator* allocator);

// TODO(jochen): Remove.
explicit IsolateHolder(v8::Isolate* isolate);

~IsolateHolder();

v8::Isolate* isolate() { return isolate_; }

private:
void Init();
void Init(v8::ArrayBuffer::Allocator* allocator);

bool isolate_owner_;
v8::Isolate* isolate_;
Expand Down

0 comments on commit 73dcce9

Please sign in to comment.