Skip to content

Commit

Permalink
Version 4.3.61.17 (cherry-pick)
Browse files Browse the repository at this point in the history
Merged ad854ea

Allow for accessing an ArrayBuffer contents without externalizing it

TBR=danno@chromium.org
BUG=

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

Cr-Commit-Position: refs/branch-heads/4.3@{crosswalk-project#20}
Cr-Branched-From: f5c0a23-refs/heads/4.3.61@{#1}
Cr-Branched-From: 0a7d4f4-refs/heads/master@{#27508}
  • Loading branch information
jeisinger committed Apr 30, 2015
1 parent 92a4588 commit d0ea36b
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 12 deletions.
2 changes: 1 addition & 1 deletion include/v8-version.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 4
#define V8_MINOR_VERSION 3
#define V8_BUILD_NUMBER 61
#define V8_PATCH_LEVEL 16
#define V8_PATCH_LEVEL 17

// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
Expand Down
23 changes: 20 additions & 3 deletions include/v8.h
Original file line number Diff line number Diff line change
Expand Up @@ -3294,6 +3294,10 @@ class V8_EXPORT Promise : public Object {
#define V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT 2
#endif


enum class ArrayBufferCreationMode { kInternalized, kExternalized };


/**
* An instance of the built-in ArrayBuffer constructor (ES6 draft 15.13.5).
* This API is experimental and may change significantly.
Expand Down Expand Up @@ -3369,12 +3373,13 @@ class V8_EXPORT ArrayBuffer : public Object {

/**
* Create a new ArrayBuffer over an existing memory block.
* The created array buffer is immediately in externalized state.
* The created array buffer is by default immediately in externalized state.
* The memory block will not be reclaimed when a created ArrayBuffer
* is garbage-collected.
*/
static Local<ArrayBuffer> New(Isolate* isolate, void* data,
size_t byte_length);
static Local<ArrayBuffer> New(
Isolate* isolate, void* data, size_t byte_length,
ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized);

/**
* Returns true if ArrayBuffer is extrenalized, that is, does not
Expand Down Expand Up @@ -3406,6 +3411,18 @@ class V8_EXPORT ArrayBuffer : public Object {
*/
Contents Externalize();

/**
* Get a pointer to the ArrayBuffer's underlying memory block without
* externalizing it. If the ArrayBuffer is not externalized, this pointer
* will become invalid as soon as the ArrayBuffer became garbage collected.
*
* The embedder should make sure to hold a strong reference to the
* ArrayBuffer while accessing this pointer.
*
* The memory block is guaranteed to be allocated with |Allocator::Allocate|.
*/
Contents GetContents();

V8_INLINE static ArrayBuffer* Cast(Value* obj);

static const int kInternalFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT;
Expand Down
24 changes: 16 additions & 8 deletions src/api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6362,14 +6362,19 @@ bool v8::ArrayBuffer::IsNeuterable() const {


v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
Utils::ApiCheck(!obj->is_external(),
"v8::ArrayBuffer::Externalize",
i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
Utils::ApiCheck(!self->is_external(), "v8::ArrayBuffer::Externalize",
"ArrayBuffer already externalized");
obj->set_is_external(true);
size_t byte_length = static_cast<size_t>(obj->byte_length()->Number());
self->set_is_external(true);
return GetContents();
}


v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() {
i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
Contents contents;
contents.data_ = obj->backing_store();
contents.data_ = self->backing_store();
contents.byte_length_ = byte_length;
return contents;
}
Expand Down Expand Up @@ -6407,13 +6412,16 @@ Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {


Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
size_t byte_length) {
size_t byte_length,
ArrayBufferCreationMode mode) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
ENTER_V8(i_isolate);
i::Handle<i::JSArrayBuffer> obj =
i_isolate->factory()->NewJSArrayBuffer();
i::Runtime::SetupArrayBuffer(i_isolate, obj, true, data, byte_length);
i::Runtime::SetupArrayBuffer(i_isolate, obj,
mode == ArrayBufferCreationMode::kExternalized,
data, byte_length);
return Utils::ToLocal(obj);
}

Expand Down
13 changes: 13 additions & 0 deletions test/cctest/test-typedarrays.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "src/api.h"
#include "src/heap/heap.h"
#include "src/objects.h"
#include "src/v8.h"

using namespace v8::internal;

Expand Down Expand Up @@ -66,3 +67,15 @@ TEST(CopyContentsView) {
"var a = new DataView(b, 2);");
TestArrayBufferViewContents(env, true);
}


TEST(AllocateNotExternal) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
void* memory = V8::ArrayBufferAllocator()->Allocate(1024);
v8::Local<v8::ArrayBuffer> buffer =
v8::ArrayBuffer::New(env->GetIsolate(), memory, 1024,
v8::ArrayBufferCreationMode::kInternalized);
CHECK(!buffer->IsExternal());
CHECK_EQ(memory, buffer->GetContents().Data());
}

0 comments on commit d0ea36b

Please sign in to comment.