Provide a convenience array buffer allocator

BUG=none
R=ulan@chromium.org

Review-Url: https://codereview.chromium.org/2101413002
Cr-Commit-Position: refs/heads/master@{#37365}
diff --git a/include/v8.h b/include/v8.h
index 8b8507f..80c34e0 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -3487,8 +3487,6 @@
    *
    * Note that it is unsafe to call back into V8 from any of the allocator
    * functions.
-   *
-   * This API is experimental and may change significantly.
    */
   class V8_EXPORT Allocator { // NOLINT
    public:
@@ -3505,11 +3503,19 @@
      * Memory does not have to be initialized.
      */
     virtual void* AllocateUninitialized(size_t length) = 0;
+
     /**
      * Free the memory block of size |length|, pointed to by |data|.
      * That memory is guaranteed to be previously allocated by |Allocate|.
      */
     virtual void Free(void* data, size_t length) = 0;
+
+    /**
+     * malloc/free based convenience allocator.
+     *
+     * Caller takes ownership.
+     */
+    static Allocator* NewDefaultAllocator();
   };
 
   /**
diff --git a/samples/hello-world.cc b/samples/hello-world.cc
index 902d8d5..9e5188f 100644
--- a/samples/hello-world.cc
+++ b/samples/hello-world.cc
@@ -11,17 +11,6 @@
 
 using namespace v8;
 
-class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
- public:
-  virtual void* Allocate(size_t length) {
-    void* data = AllocateUninitialized(length);
-    return data == NULL ? data : memset(data, 0, length);
-  }
-  virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
-  virtual void Free(void* data, size_t) { free(data); }
-};
-
-
 int main(int argc, char* argv[]) {
   // Initialize V8.
   V8::InitializeICUDefaultLocation(argv[0]);
@@ -31,9 +20,9 @@
   V8::Initialize();
 
   // Create a new Isolate and make it the current one.
-  ArrayBufferAllocator allocator;
   Isolate::CreateParams create_params;
-  create_params.array_buffer_allocator = &allocator;
+  create_params.array_buffer_allocator =
+      v8::ArrayBuffer::Allocator::NewDefaultAllocator();
   Isolate* isolate = Isolate::New(create_params);
   {
     Isolate::Scope isolate_scope(isolate);
@@ -68,5 +57,6 @@
   V8::Dispose();
   V8::ShutdownPlatform();
   delete platform;
+  delete create_params.array_buffer_allocator;
   return 0;
 }
diff --git a/samples/process.cc b/samples/process.cc
index 54c8376..29ddb5c 100644
--- a/samples/process.cc
+++ b/samples/process.cc
@@ -38,17 +38,6 @@
 using namespace std;
 using namespace v8;
 
-class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
- public:
-  virtual void* Allocate(size_t length) {
-    void* data = AllocateUninitialized(length);
-    return data == NULL ? data : memset(data, 0, length);
-  }
-  virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
-  virtual void Free(void* data, size_t) { free(data); }
-};
-
-
 // These interfaces represent an existing request processing interface.
 // The idea is to imagine a real application that uses these interfaces
 // and then add scripting capabilities that allow you to interact with
@@ -699,9 +688,9 @@
     fprintf(stderr, "No script was specified.\n");
     return 1;
   }
-  ArrayBufferAllocator array_buffer_allocator;
   Isolate::CreateParams create_params;
-  create_params.array_buffer_allocator = &array_buffer_allocator;
+  create_params.array_buffer_allocator =
+      v8::ArrayBuffer::Allocator::NewDefaultAllocator();
   Isolate* isolate = Isolate::New(create_params);
   Isolate::Scope isolate_scope(isolate);
   HandleScope scope(isolate);
diff --git a/samples/shell.cc b/samples/shell.cc
index ad9b1ab..e042815 100644
--- a/samples/shell.cc
+++ b/samples/shell.cc
@@ -63,17 +63,6 @@
 static bool run_shell;
 
 
-class ShellArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
- public:
-  virtual void* Allocate(size_t length) {
-    void* data = AllocateUninitialized(length);
-    return data == NULL ? data : memset(data, 0, length);
-  }
-  virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
-  virtual void Free(void* data, size_t) { free(data); }
-};
-
-
 int main(int argc, char* argv[]) {
   v8::V8::InitializeICUDefaultLocation(argv[0]);
   v8::V8::InitializeExternalStartupData(argv[0]);
@@ -81,9 +70,9 @@
   v8::V8::InitializePlatform(platform);
   v8::V8::Initialize();
   v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
-  ShellArrayBufferAllocator array_buffer_allocator;
   v8::Isolate::CreateParams create_params;
-  create_params.array_buffer_allocator = &array_buffer_allocator;
+  create_params.array_buffer_allocator =
+      v8::ArrayBuffer::Allocator::NewDefaultAllocator();
   v8::Isolate* isolate = v8::Isolate::New(create_params);
   run_shell = (argc == 1);
   int result;
@@ -103,6 +92,7 @@
   v8::V8::Dispose();
   v8::V8::ShutdownPlatform();
   delete platform;
+  delete create_params.array_buffer_allocator;
   return result;
 }
 
diff --git a/src/api.cc b/src/api.cc
index 86135fd..7268eee 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -6749,6 +6749,11 @@
   RETURN_ESCAPED(result);
 }
 
+// static
+v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
+  return new ArrayBufferAllocator();
+}
+
 bool v8::ArrayBuffer::IsExternal() const {
   return Utils::OpenHandle(this)->is_external();
 }
diff --git a/test/cctest/interpreter/generate-bytecode-expectations.cc b/test/cctest/interpreter/generate-bytecode-expectations.cc
index 53f2e3f..f823759 100644
--- a/test/cctest/interpreter/generate-bytecode-expectations.cc
+++ b/test/cctest/interpreter/generate-bytecode-expectations.cc
@@ -93,17 +93,6 @@
   std::string test_function_name_;
 };
 
-class ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator {
- public:
-  void* Allocate(size_t length) override {
-    void* data = AllocateUninitialized(length);
-    if (data != nullptr) memset(data, 0, length);
-    return data;
-  }
-  void* AllocateUninitialized(size_t length) override { return malloc(length); }
-  void Free(void* data, size_t) override { free(data); }
-};
-
 class V8InitializationScope final {
  public:
   explicit V8InitializationScope(const char* exec_path);
@@ -114,6 +103,7 @@
 
  private:
   v8::base::SmartPointer<v8::Platform> platform_;
+  v8::base::SmartPointer<v8::ArrayBuffer::Allocator> allocator_;
   v8::Isolate* isolate_;
 
   DISALLOW_COPY_AND_ASSIGN(V8InitializationScope);
@@ -363,9 +353,9 @@
   v8::V8::InitializePlatform(platform_.get());
   v8::V8::Initialize();
 
-  ArrayBufferAllocator allocator;
   v8::Isolate::CreateParams create_params;
-  create_params.array_buffer_allocator = &allocator;
+  allocator_.Reset(v8::ArrayBuffer::Allocator::NewDefaultAllocator());
+  create_params.array_buffer_allocator = allocator_.get();
 
   isolate_ = v8::Isolate::New(create_params);
 }
diff --git a/test/fuzzer/fuzzer-support.cc b/test/fuzzer/fuzzer-support.cc
index ea9fb09..936970e 100644
--- a/test/fuzzer/fuzzer-support.cc
+++ b/test/fuzzer/fuzzer-support.cc
@@ -27,16 +27,6 @@
 
 }  // namespace
 
-class FuzzerSupport::ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
- public:
-  virtual void* Allocate(size_t length) {
-    void* data = AllocateUninitialized(length);
-    return data == NULL ? data : memset(data, 0, length);
-  }
-  virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
-  virtual void Free(void* data, size_t) { free(data); }
-};
-
 FuzzerSupport::FuzzerSupport(int* argc, char*** argv) {
   v8::internal::FLAG_expose_gc = true;
   v8::V8::SetFlagsFromCommandLine(argc, *argv, true);
@@ -46,7 +36,7 @@
   v8::V8::InitializePlatform(platform_);
   v8::V8::Initialize();
 
-  allocator_ = new ArrayBufferAllocator;
+  allocator_ = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
   v8::Isolate::CreateParams create_params;
   create_params.array_buffer_allocator = allocator_;
   isolate_ = v8::Isolate::New(create_params);
diff --git a/test/fuzzer/fuzzer-support.h b/test/fuzzer/fuzzer-support.h
index 0241c53..c941c9c 100644
--- a/test/fuzzer/fuzzer-support.h
+++ b/test/fuzzer/fuzzer-support.h
@@ -24,10 +24,9 @@
   FuzzerSupport(const FuzzerSupport&);
   FuzzerSupport& operator=(const FuzzerSupport&);
 
-  class ArrayBufferAllocator;
 
   v8::Platform* platform_;
-  ArrayBufferAllocator* allocator_;
+  v8::ArrayBuffer::Allocator* allocator_;
   v8::Isolate* isolate_;
   v8::Global<v8::Context> context_;
 };
diff --git a/test/unittests/test-utils.cc b/test/unittests/test-utils.cc
index 7d04215..6ac71d2 100644
--- a/test/unittests/test-utils.cc
+++ b/test/unittests/test-utils.cc
@@ -13,23 +13,11 @@
 
 namespace v8 {
 
-class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
- public:
-  virtual void* Allocate(size_t length) {
-    void* data = AllocateUninitialized(length);
-    return data == NULL ? data : memset(data, 0, length);
-  }
-  virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
-  virtual void Free(void* data, size_t) { free(data); }
-};
-
+// static
+v8::ArrayBuffer::Allocator* TestWithIsolate::array_buffer_allocator_ = nullptr;
 
 // static
-ArrayBufferAllocator* TestWithIsolate::array_buffer_allocator_ = NULL;
-
-// static
-Isolate* TestWithIsolate::isolate_ = NULL;
-
+Isolate* TestWithIsolate::isolate_ = nullptr;
 
 TestWithIsolate::TestWithIsolate()
     : isolate_scope_(isolate()), handle_scope_(isolate()) {}
@@ -43,7 +31,7 @@
   Test::SetUpTestCase();
   EXPECT_EQ(NULL, isolate_);
   v8::Isolate::CreateParams create_params;
-  array_buffer_allocator_ = new ArrayBufferAllocator;
+  array_buffer_allocator_ = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
   create_params.array_buffer_allocator = array_buffer_allocator_;
   isolate_ = v8::Isolate::New(create_params);
   EXPECT_TRUE(isolate_ != NULL);
diff --git a/test/unittests/test-utils.h b/test/unittests/test-utils.h
index 1342510..433a1f2f 100644
--- a/test/unittests/test-utils.h
+++ b/test/unittests/test-utils.h
@@ -27,7 +27,7 @@
   static void TearDownTestCase();
 
  private:
-  static ArrayBufferAllocator* array_buffer_allocator_;
+  static v8::ArrayBuffer::Allocator* array_buffer_allocator_;
   static Isolate* isolate_;
   Isolate::Scope isolate_scope_;
   HandleScope handle_scope_;
diff --git a/tools/parser-shell.cc b/tools/parser-shell.cc
index 810c5b9..f4e5440 100644
--- a/tools/parser-shell.cc
+++ b/tools/parser-shell.cc
@@ -45,16 +45,6 @@
 
 using namespace v8::internal;
 
-class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
- public:
-  virtual void* Allocate(size_t length) {
-    void* data = AllocateUninitialized(length);
-    return data == NULL ? data : memset(data, 0, length);
-  }
-  virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
-  virtual void Free(void* data, size_t) { free(data); }
-};
-
 class StringResource8 : public v8::String::ExternalOneByteStringResource {
  public:
   StringResource8(const char* data, int length)
@@ -168,9 +158,9 @@
       fnames.push_back(std::string(argv[i]));
     }
   }
-  ArrayBufferAllocator array_buffer_allocator;
   v8::Isolate::CreateParams create_params;
-  create_params.array_buffer_allocator = &array_buffer_allocator;
+  create_params.array_buffer_allocator =
+      v8::ArrayBuffer::Allocator::NewDefaultAllocator();
   v8::Isolate* isolate = v8::Isolate::New(create_params);
   {
     v8::Isolate::Scope isolate_scope(isolate);
@@ -199,5 +189,6 @@
   v8::V8::Dispose();
   v8::V8::ShutdownPlatform();
   delete platform;
+  delete create_params.array_buffer_allocator;
   return 0;
 }