Commit 6d266f00 authored by titzer's avatar titzer Committed by Commit bot

[wasm] Add a Managed<T> wrapper class for allocating C++ classes that are...

[wasm] Add a Managed<T> wrapper class for allocating C++ classes that are deleted when the wrapper is garbage collected.

Use sparingly!

This doesn't add any really new functionality, other than making it more
convenient to do this.

This will primarily be used to wrap a WasmModule to be referenced from a
JSObject that represents an instance. There is one WasmModule C++ object
per parsed WasmModule, so this should not be more than a handful or a few
dozen in well-behaved programs.

R=rossberg@chromium.org,mlippautz@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/2409173005
Cr-Commit-Position: refs/heads/master@{#40346}
parent f87d19c4
......@@ -1713,6 +1713,7 @@ v8_source_set("v8_base") {
"src/wasm/ast-decoder.h",
"src/wasm/decoder.h",
"src/wasm/leb-helper.h",
"src/wasm/managed.h",
"src/wasm/module-decoder.cc",
"src/wasm/module-decoder.h",
"src/wasm/signature-map.cc",
......
......@@ -1251,6 +1251,7 @@
'wasm/ast-decoder.h',
'wasm/decoder.h',
'wasm/leb-helper.h',
'wasm/managed.h',
'wasm/module-decoder.cc',
'wasm/module-decoder.h',
'wasm/signature-map.cc',
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_MANAGED_H_
#define V8_WASM_MANAGED_H_
#include "src/factory.h"
#include "src/global-handles.h"
#include "src/handles.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
namespace v8 {
namespace internal {
// An object that wraps a pointer to a C++ object and optionally deletes it
// when the managed wrapper object is garbage collected.
template <class CppType>
class Managed : public Foreign {
public:
V8_INLINE CppType* get() {
return reinterpret_cast<CppType*>(foreign_address());
}
static Handle<Managed<CppType>> New(Isolate* isolate, CppType* ptr,
bool delete_on_gc = true) {
Handle<Foreign> foreign =
isolate->factory()->NewForeign(reinterpret_cast<Address>(ptr));
Handle<Managed<CppType>> handle(
reinterpret_cast<Managed<CppType>*>(*foreign), isolate);
if (delete_on_gc) {
RegisterWeakCallbackForDelete(isolate, handle);
}
return handle;
}
private:
static void RegisterWeakCallbackForDelete(Isolate* isolate,
Handle<Managed<CppType>> handle) {
Handle<Object> global_handle = isolate->global_handles()->Create(*handle);
GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(),
&Managed<CppType>::Delete,
v8::WeakCallbackType::kFinalizer);
}
static void Delete(const v8::WeakCallbackInfo<void>& data) {
Managed<CppType>** p =
reinterpret_cast<Managed<CppType>**>(data.GetParameter());
delete (*p)->get();
GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
}
};
} // namespace internal
} // namespace v8
#endif // V8_WASM_MANAGED_H_
......@@ -182,6 +182,7 @@ v8_executable("cctest") {
"trace-extension.cc",
"trace-extension.h",
"types-fuzz.h",
"wasm/test-managed.cc",
"wasm/test-run-wasm-64.cc",
"wasm/test-run-wasm-asmjs.cc",
"wasm/test-run-wasm-interpreter.cc",
......
......@@ -203,6 +203,7 @@
'trace-extension.cc',
'trace-extension.h',
'types-fuzz.h',
'wasm/test-managed.cc',
'wasm/test-run-wasm.cc',
'wasm/test-run-wasm-64.cc',
'wasm/test-run-wasm-asmjs.cc',
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "src/wasm/managed.h"
#include "test/cctest/cctest.h"
#include "test/common/wasm/test-signatures.h"
using namespace v8::base;
using namespace v8::internal;
class DeleteRecorder {
public:
explicit DeleteRecorder(bool* deleted) : deleted_(deleted) {
*deleted_ = false;
}
~DeleteRecorder() { *deleted_ = true; }
private:
bool* deleted_;
};
TEST(ManagedCollect) {
Isolate* isolate = CcTest::InitIsolateOnce();
bool deleted = false;
DeleteRecorder* d = new DeleteRecorder(&deleted);
{
HandleScope scope(isolate);
auto handle = Managed<DeleteRecorder>::New(isolate, d);
USE(handle);
}
CcTest::CollectAllAvailableGarbage();
CHECK(deleted);
}
TEST(ManagedCollectNoDelete) {
Isolate* isolate = CcTest::InitIsolateOnce();
bool deleted = false;
DeleteRecorder* d = new DeleteRecorder(&deleted);
{
HandleScope scope(isolate);
auto handle = Managed<DeleteRecorder>::New(isolate, d, false);
USE(handle);
}
CcTest::CollectAllAvailableGarbage();
CHECK(!deleted);
delete d;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment