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_