Upgrade to 3.29
Update V8 to 3.29.88.17 and update makefiles to support building on
all the relevant platforms.
Bug: 17370214
Change-Id: Ia3407c157fd8d72a93e23d8318ccaf6ecf77fa4e
diff --git a/src/libplatform/DEPS b/src/libplatform/DEPS
new file mode 100644
index 0000000..2ea3359
--- /dev/null
+++ b/src/libplatform/DEPS
@@ -0,0 +1,8 @@
+include_rules = [
+ "-include",
+ "+include/libplatform",
+ "+include/v8-platform.h",
+ "-src",
+ "+src/base",
+ "+src/libplatform",
+]
diff --git a/src/libplatform/default-platform-unittest.cc b/src/libplatform/default-platform-unittest.cc
new file mode 100644
index 0000000..d2c160e
--- /dev/null
+++ b/src/libplatform/default-platform-unittest.cc
@@ -0,0 +1,43 @@
+// Copyright 2014 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 "src/libplatform/default-platform.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::InSequence;
+using testing::StrictMock;
+
+namespace v8 {
+namespace platform {
+
+namespace {
+
+struct MockTask : public Task {
+ virtual ~MockTask() { Die(); }
+ MOCK_METHOD0(Run, void());
+ MOCK_METHOD0(Die, void());
+};
+
+} // namespace
+
+
+TEST(DefaultPlatformTest, PumpMessageLoop) {
+ InSequence s;
+
+ int dummy;
+ Isolate* isolate = reinterpret_cast<Isolate*>(&dummy);
+
+ DefaultPlatform platform;
+ EXPECT_FALSE(platform.PumpMessageLoop(isolate));
+
+ StrictMock<MockTask>* task = new StrictMock<MockTask>;
+ platform.CallOnForegroundThread(isolate, task);
+ EXPECT_CALL(*task, Run());
+ EXPECT_CALL(*task, Die());
+ EXPECT_TRUE(platform.PumpMessageLoop(isolate));
+ EXPECT_FALSE(platform.PumpMessageLoop(isolate));
+}
+
+} // namespace platform
+} // namespace v8
diff --git a/src/libplatform/default-platform.cc b/src/libplatform/default-platform.cc
new file mode 100644
index 0000000..b5b8571
--- /dev/null
+++ b/src/libplatform/default-platform.cc
@@ -0,0 +1,109 @@
+// Copyright 2013 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 "src/libplatform/default-platform.h"
+
+#include <algorithm>
+#include <queue>
+
+#include "src/base/logging.h"
+#include "src/base/platform/platform.h"
+#include "src/base/sys-info.h"
+#include "src/libplatform/worker-thread.h"
+
+namespace v8 {
+namespace platform {
+
+
+v8::Platform* CreateDefaultPlatform(int thread_pool_size) {
+ DefaultPlatform* platform = new DefaultPlatform();
+ platform->SetThreadPoolSize(thread_pool_size);
+ platform->EnsureInitialized();
+ return platform;
+}
+
+
+bool PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate) {
+ return reinterpret_cast<DefaultPlatform*>(platform)->PumpMessageLoop(isolate);
+}
+
+
+const int DefaultPlatform::kMaxThreadPoolSize = 4;
+
+
+DefaultPlatform::DefaultPlatform()
+ : initialized_(false), thread_pool_size_(0) {}
+
+
+DefaultPlatform::~DefaultPlatform() {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ queue_.Terminate();
+ if (initialized_) {
+ for (std::vector<WorkerThread*>::iterator i = thread_pool_.begin();
+ i != thread_pool_.end(); ++i) {
+ delete *i;
+ }
+ }
+ for (std::map<v8::Isolate*, std::queue<Task*> >::iterator i =
+ main_thread_queue_.begin();
+ i != main_thread_queue_.end(); ++i) {
+ while (!i->second.empty()) {
+ delete i->second.front();
+ i->second.pop();
+ }
+ }
+}
+
+
+void DefaultPlatform::SetThreadPoolSize(int thread_pool_size) {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ DCHECK(thread_pool_size >= 0);
+ if (thread_pool_size < 1) {
+ thread_pool_size = base::SysInfo::NumberOfProcessors();
+ }
+ thread_pool_size_ =
+ std::max(std::min(thread_pool_size, kMaxThreadPoolSize), 1);
+}
+
+
+void DefaultPlatform::EnsureInitialized() {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ if (initialized_) return;
+ initialized_ = true;
+
+ for (int i = 0; i < thread_pool_size_; ++i)
+ thread_pool_.push_back(new WorkerThread(&queue_));
+}
+
+
+bool DefaultPlatform::PumpMessageLoop(v8::Isolate* isolate) {
+ Task* task = NULL;
+ {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ std::map<v8::Isolate*, std::queue<Task*> >::iterator it =
+ main_thread_queue_.find(isolate);
+ if (it == main_thread_queue_.end() || it->second.empty()) {
+ return false;
+ }
+ task = it->second.front();
+ it->second.pop();
+ }
+ task->Run();
+ delete task;
+ return true;
+}
+
+void DefaultPlatform::CallOnBackgroundThread(Task *task,
+ ExpectedRuntime expected_runtime) {
+ EnsureInitialized();
+ queue_.Append(task);
+}
+
+
+void DefaultPlatform::CallOnForegroundThread(v8::Isolate* isolate, Task* task) {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ main_thread_queue_[isolate].push(task);
+}
+
+} } // namespace v8::platform
diff --git a/src/libplatform/default-platform.h b/src/libplatform/default-platform.h
new file mode 100644
index 0000000..1efd7b2
--- /dev/null
+++ b/src/libplatform/default-platform.h
@@ -0,0 +1,58 @@
+// Copyright 2013 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_LIBPLATFORM_DEFAULT_PLATFORM_H_
+#define V8_LIBPLATFORM_DEFAULT_PLATFORM_H_
+
+#include <map>
+#include <queue>
+#include <vector>
+
+#include "include/v8-platform.h"
+#include "src/base/macros.h"
+#include "src/base/platform/mutex.h"
+#include "src/libplatform/task-queue.h"
+
+namespace v8 {
+namespace platform {
+
+class TaskQueue;
+class Thread;
+class WorkerThread;
+
+class DefaultPlatform : public Platform {
+ public:
+ DefaultPlatform();
+ virtual ~DefaultPlatform();
+
+ void SetThreadPoolSize(int thread_pool_size);
+
+ void EnsureInitialized();
+
+ bool PumpMessageLoop(v8::Isolate* isolate);
+
+ // v8::Platform implementation.
+ virtual void CallOnBackgroundThread(
+ Task* task, ExpectedRuntime expected_runtime) OVERRIDE;
+ virtual void CallOnForegroundThread(v8::Isolate* isolate,
+ Task* task) OVERRIDE;
+
+ private:
+ static const int kMaxThreadPoolSize;
+
+ base::Mutex lock_;
+ bool initialized_;
+ int thread_pool_size_;
+ std::vector<WorkerThread*> thread_pool_;
+ TaskQueue queue_;
+ std::map<v8::Isolate*, std::queue<Task*> > main_thread_queue_;
+
+ DISALLOW_COPY_AND_ASSIGN(DefaultPlatform);
+};
+
+
+} } // namespace v8::platform
+
+
+#endif // V8_LIBPLATFORM_DEFAULT_PLATFORM_H_
diff --git a/src/libplatform/libplatform.gyp b/src/libplatform/libplatform.gyp
new file mode 100644
index 0000000..4321da7
--- /dev/null
+++ b/src/libplatform/libplatform.gyp
@@ -0,0 +1,39 @@
+# Copyright 2014 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.
+
+{
+ 'variables': {
+ 'v8_code': 1,
+ },
+ 'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
+ 'targets': [
+ {
+ 'target_name': 'libplatform-unittests',
+ 'type': 'executable',
+ 'dependencies': [
+ '../../testing/gtest.gyp:gtest',
+ '../../testing/gmock.gyp:gmock',
+ '../../testing/gmock.gyp:gmock_main',
+ '../../tools/gyp/v8.gyp:v8_libplatform',
+ ],
+ 'include_dirs': [
+ '../..',
+ ],
+ 'sources': [ ### gcmole(all) ###
+ 'default-platform-unittest.cc',
+ 'task-queue-unittest.cc',
+ 'worker-thread-unittest.cc',
+ ],
+ 'conditions': [
+ ['os_posix == 1', {
+ # TODO(svenpanne): This is a temporary work-around to fix the warnings
+ # that show up because we use -std=gnu++0x instead of -std=c++11.
+ 'cflags!': [
+ '-pedantic',
+ ],
+ }],
+ ],
+ },
+ ],
+}
diff --git a/src/libplatform/task-queue-unittest.cc b/src/libplatform/task-queue-unittest.cc
new file mode 100644
index 0000000..9a18658
--- /dev/null
+++ b/src/libplatform/task-queue-unittest.cc
@@ -0,0 +1,60 @@
+// Copyright 2014 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 "include/v8-platform.h"
+#include "src/base/platform/platform.h"
+#include "src/libplatform/task-queue.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::InSequence;
+using testing::IsNull;
+using testing::StrictMock;
+
+namespace v8 {
+namespace platform {
+
+namespace {
+
+struct MockTask : public Task {
+ MOCK_METHOD0(Run, void());
+};
+
+
+class TaskQueueThread FINAL : public base::Thread {
+ public:
+ explicit TaskQueueThread(TaskQueue* queue)
+ : Thread(Options("libplatform TaskQueueThread")), queue_(queue) {}
+
+ virtual void Run() OVERRIDE { EXPECT_THAT(queue_->GetNext(), IsNull()); }
+
+ private:
+ TaskQueue* queue_;
+};
+
+} // namespace
+
+
+TEST(TaskQueueTest, Basic) {
+ TaskQueue queue;
+ MockTask task;
+ queue.Append(&task);
+ EXPECT_EQ(&task, queue.GetNext());
+ queue.Terminate();
+ EXPECT_THAT(queue.GetNext(), IsNull());
+}
+
+
+TEST(TaskQueueTest, TerminateMultipleReaders) {
+ TaskQueue queue;
+ TaskQueueThread thread1(&queue);
+ TaskQueueThread thread2(&queue);
+ thread1.Start();
+ thread2.Start();
+ queue.Terminate();
+ thread1.Join();
+ thread2.Join();
+}
+
+} // namespace platform
+} // namespace v8
diff --git a/src/libplatform/task-queue.cc b/src/libplatform/task-queue.cc
new file mode 100644
index 0000000..7a9071f
--- /dev/null
+++ b/src/libplatform/task-queue.cc
@@ -0,0 +1,56 @@
+// Copyright 2013 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 "src/libplatform/task-queue.h"
+
+#include "src/base/logging.h"
+
+namespace v8 {
+namespace platform {
+
+TaskQueue::TaskQueue() : process_queue_semaphore_(0), terminated_(false) {}
+
+
+TaskQueue::~TaskQueue() {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ DCHECK(terminated_);
+ DCHECK(task_queue_.empty());
+}
+
+
+void TaskQueue::Append(Task* task) {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ DCHECK(!terminated_);
+ task_queue_.push(task);
+ process_queue_semaphore_.Signal();
+}
+
+
+Task* TaskQueue::GetNext() {
+ for (;;) {
+ {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ if (!task_queue_.empty()) {
+ Task* result = task_queue_.front();
+ task_queue_.pop();
+ return result;
+ }
+ if (terminated_) {
+ process_queue_semaphore_.Signal();
+ return NULL;
+ }
+ }
+ process_queue_semaphore_.Wait();
+ }
+}
+
+
+void TaskQueue::Terminate() {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ DCHECK(!terminated_);
+ terminated_ = true;
+ process_queue_semaphore_.Signal();
+}
+
+} } // namespace v8::platform
diff --git a/src/libplatform/task-queue.h b/src/libplatform/task-queue.h
new file mode 100644
index 0000000..eb9d698
--- /dev/null
+++ b/src/libplatform/task-queue.h
@@ -0,0 +1,47 @@
+// Copyright 2013 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_LIBPLATFORM_TASK_QUEUE_H_
+#define V8_LIBPLATFORM_TASK_QUEUE_H_
+
+#include <queue>
+
+#include "src/base/macros.h"
+#include "src/base/platform/mutex.h"
+#include "src/base/platform/semaphore.h"
+
+namespace v8 {
+
+class Task;
+
+namespace platform {
+
+class TaskQueue {
+ public:
+ TaskQueue();
+ ~TaskQueue();
+
+ // Appends a task to the queue. The queue takes ownership of |task|.
+ void Append(Task* task);
+
+ // Returns the next task to process. Blocks if no task is available. Returns
+ // NULL if the queue is terminated.
+ Task* GetNext();
+
+ // Terminate the queue.
+ void Terminate();
+
+ private:
+ base::Mutex lock_;
+ base::Semaphore process_queue_semaphore_;
+ std::queue<Task*> task_queue_;
+ bool terminated_;
+
+ DISALLOW_COPY_AND_ASSIGN(TaskQueue);
+};
+
+} } // namespace v8::platform
+
+
+#endif // V8_LIBPLATFORM_TASK_QUEUE_H_
diff --git a/src/libplatform/worker-thread-unittest.cc b/src/libplatform/worker-thread-unittest.cc
new file mode 100644
index 0000000..175b311
--- /dev/null
+++ b/src/libplatform/worker-thread-unittest.cc
@@ -0,0 +1,48 @@
+// Copyright 2014 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 "include/v8-platform.h"
+#include "src/libplatform/task-queue.h"
+#include "src/libplatform/worker-thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::InSequence;
+using testing::IsNull;
+using testing::StrictMock;
+
+namespace v8 {
+namespace platform {
+
+namespace {
+
+struct MockTask : public Task {
+ virtual ~MockTask() { Die(); }
+ MOCK_METHOD0(Run, void());
+ MOCK_METHOD0(Die, void());
+};
+
+} // namespace
+
+
+TEST(WorkerThreadTest, Basic) {
+ static const size_t kNumTasks = 10;
+
+ TaskQueue queue;
+ for (size_t i = 0; i < kNumTasks; ++i) {
+ InSequence s;
+ StrictMock<MockTask>* task = new StrictMock<MockTask>;
+ EXPECT_CALL(*task, Run());
+ EXPECT_CALL(*task, Die());
+ queue.Append(task);
+ }
+
+ WorkerThread thread1(&queue);
+ WorkerThread thread2(&queue);
+
+ // TaskQueue DCHECKS that it's empty in its destructor.
+ queue.Terminate();
+}
+
+} // namespace platform
+} // namespace v8
diff --git a/src/libplatform/worker-thread.cc b/src/libplatform/worker-thread.cc
new file mode 100644
index 0000000..9963715
--- /dev/null
+++ b/src/libplatform/worker-thread.cc
@@ -0,0 +1,31 @@
+// Copyright 2013 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 "src/libplatform/worker-thread.h"
+
+#include "include/v8-platform.h"
+#include "src/libplatform/task-queue.h"
+
+namespace v8 {
+namespace platform {
+
+WorkerThread::WorkerThread(TaskQueue* queue)
+ : Thread(Options("V8 WorkerThread")), queue_(queue) {
+ Start();
+}
+
+
+WorkerThread::~WorkerThread() {
+ Join();
+}
+
+
+void WorkerThread::Run() {
+ while (Task* task = queue_->GetNext()) {
+ task->Run();
+ delete task;
+ }
+}
+
+} } // namespace v8::platform
diff --git a/src/libplatform/worker-thread.h b/src/libplatform/worker-thread.h
new file mode 100644
index 0000000..67f086d
--- /dev/null
+++ b/src/libplatform/worker-thread.h
@@ -0,0 +1,38 @@
+// Copyright 2013 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_LIBPLATFORM_WORKER_THREAD_H_
+#define V8_LIBPLATFORM_WORKER_THREAD_H_
+
+#include <queue>
+
+#include "src/base/macros.h"
+#include "src/base/platform/platform.h"
+
+namespace v8 {
+
+namespace platform {
+
+class TaskQueue;
+
+class WorkerThread : public base::Thread {
+ public:
+ explicit WorkerThread(TaskQueue* queue);
+ virtual ~WorkerThread();
+
+ // Thread implementation.
+ virtual void Run() OVERRIDE;
+
+ private:
+ friend class QuitTask;
+
+ TaskQueue* queue_;
+
+ DISALLOW_COPY_AND_ASSIGN(WorkerThread);
+};
+
+} } // namespace v8::platform
+
+
+#endif // V8_LIBPLATFORM_WORKER_THREAD_H_