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/v8threads.cc b/src/v8threads.cc
index fd8d536..a46b289 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -1,38 +1,15 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright 2012 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 "v8.h"
+#include "src/v8.h"
 
-#include "api.h"
-#include "bootstrapper.h"
-#include "debug.h"
-#include "execution.h"
-#include "v8threads.h"
-#include "regexp-stack.h"
+#include "src/api.h"
+#include "src/bootstrapper.h"
+#include "src/debug.h"
+#include "src/execution.h"
+#include "src/regexp-stack.h"
+#include "src/v8threads.h"
 
 namespace v8 {
 
@@ -42,15 +19,13 @@
 bool Locker::active_ = false;
 
 
-// Constructor for the Locker object.  Once the Locker is constructed the
-// current thread will be guaranteed to have the lock for a given isolate.
-Locker::Locker(v8::Isolate* isolate)
-  : has_lock_(false),
-    top_level_(true),
-    isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
-  if (isolate_ == NULL) {
-    isolate_ = i::Isolate::GetDefaultIsolateForLocking();
-  }
+// Once the Locker is initialized, the current thread will be guaranteed to have
+// the lock for a given isolate.
+void Locker::Initialize(v8::Isolate* isolate) {
+  DCHECK(isolate != NULL);
+  has_lock_= false;
+  top_level_ = true;
+  isolate_ = reinterpret_cast<i::Isolate*>(isolate);
   // Record that the Locker has been used at least once.
   active_ = true;
   // Get the big lock if necessary.
@@ -76,20 +51,14 @@
       isolate_->stack_guard()->ClearThread(access);
       isolate_->stack_guard()->InitThread(access);
     }
-    if (isolate_->IsDefaultIsolate()) {
-      // This only enters if not yet entered.
-      internal::Isolate::EnterDefaultIsolate();
-    }
   }
-  ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread());
+  DCHECK(isolate_->thread_manager()->IsLockedByCurrentThread());
 }
 
 
 bool Locker::IsLocked(v8::Isolate* isolate) {
+  DCHECK(isolate != NULL);
   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  if (internal_isolate == NULL) {
-    internal_isolate = i::Isolate::GetDefaultIsolateForLocking();
-  }
   return internal_isolate->thread_manager()->IsLockedByCurrentThread();
 }
 
@@ -100,11 +69,8 @@
 
 
 Locker::~Locker() {
-  ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread());
+  DCHECK(isolate_->thread_manager()->IsLockedByCurrentThread());
   if (has_lock_) {
-    if (isolate_->IsDefaultIsolate()) {
-      isolate_->Exit();
-    }
     if (top_level_) {
       isolate_->thread_manager()->FreeThreadResources();
     } else {
@@ -115,37 +81,19 @@
 }
 
 
-Unlocker::Unlocker(v8::Isolate* isolate)
-  : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
-  if (isolate_ == NULL) {
-    isolate_ = i::Isolate::GetDefaultIsolateForLocking();
-  }
-  ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread());
-  if (isolate_->IsDefaultIsolate()) {
-    isolate_->Exit();
-  }
+void Unlocker::Initialize(v8::Isolate* isolate) {
+  DCHECK(isolate != NULL);
+  isolate_ = reinterpret_cast<i::Isolate*>(isolate);
+  DCHECK(isolate_->thread_manager()->IsLockedByCurrentThread());
   isolate_->thread_manager()->ArchiveThread();
   isolate_->thread_manager()->Unlock();
 }
 
 
 Unlocker::~Unlocker() {
-  ASSERT(!isolate_->thread_manager()->IsLockedByCurrentThread());
+  DCHECK(!isolate_->thread_manager()->IsLockedByCurrentThread());
   isolate_->thread_manager()->Lock();
   isolate_->thread_manager()->RestoreThread();
-  if (isolate_->IsDefaultIsolate()) {
-    isolate_->Enter();
-  }
-}
-
-
-void Locker::StartPreemption(int every_n_ms) {
-  v8::internal::ContextSwitcher::StartPreemption(every_n_ms);
-}
-
-
-void Locker::StopPreemption() {
-  v8::internal::ContextSwitcher::StopPreemption();
 }
 
 
@@ -153,7 +101,7 @@
 
 
 bool ThreadManager::RestoreThread() {
-  ASSERT(IsLockedByCurrentThread());
+  DCHECK(IsLockedByCurrentThread());
   // First check whether the current thread has been 'lazily archived', i.e.
   // not archived at all.  If that is the case we put the state storage we
   // had prepared back in the free list, since we didn't need it after all.
@@ -161,8 +109,8 @@
     lazily_archived_thread_ = ThreadId::Invalid();
     Isolate::PerIsolateThreadData* per_thread =
         isolate_->FindPerThreadDataForThisThread();
-    ASSERT(per_thread != NULL);
-    ASSERT(per_thread->thread_state() == lazily_archived_thread_state_);
+    DCHECK(per_thread != NULL);
+    DCHECK(per_thread->thread_state() == lazily_archived_thread_state_);
     lazily_archived_thread_state_->set_id(ThreadId::Invalid());
     lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST);
     lazily_archived_thread_state_ = NULL;
@@ -191,15 +139,13 @@
   from = isolate_->handle_scope_implementer()->RestoreThread(from);
   from = isolate_->RestoreThread(from);
   from = Relocatable::RestoreState(isolate_, from);
-#ifdef ENABLE_DEBUGGER_SUPPORT
   from = isolate_->debug()->RestoreDebug(from);
-#endif
   from = isolate_->stack_guard()->RestoreStackGuard(from);
   from = isolate_->regexp_stack()->RestoreStack(from);
   from = isolate_->bootstrapper()->RestoreState(from);
   per_thread->set_thread_state(NULL);
   if (state->terminate_on_restore()) {
-    isolate_->stack_guard()->TerminateExecution();
+    isolate_->stack_guard()->RequestTerminateExecution();
     state->set_terminate_on_restore(false);
   }
   state->set_id(ThreadId::Invalid());
@@ -210,24 +156,22 @@
 
 
 void ThreadManager::Lock() {
-  mutex_->Lock();
+  mutex_.Lock();
   mutex_owner_ = ThreadId::Current();
-  ASSERT(IsLockedByCurrentThread());
+  DCHECK(IsLockedByCurrentThread());
 }
 
 
 void ThreadManager::Unlock() {
   mutex_owner_ = ThreadId::Invalid();
-  mutex_->Unlock();
+  mutex_.Unlock();
 }
 
 
 static int ArchiveSpacePerThread() {
   return HandleScopeImplementer::ArchiveSpacePerThread() +
                         Isolate::ArchiveSpacePerThread() +
-#ifdef ENABLE_DEBUGGER_SUPPORT
                           Debug::ArchiveSpacePerThread() +
-#endif
                      StackGuard::ArchiveSpacePerThread() +
                     RegExpStack::ArchiveSpacePerThread() +
                    Bootstrapper::ArchiveSpacePerThread() +
@@ -238,12 +182,18 @@
 ThreadState::ThreadState(ThreadManager* thread_manager)
     : id_(ThreadId::Invalid()),
       terminate_on_restore_(false),
+      data_(NULL),
       next_(this),
       previous_(this),
       thread_manager_(thread_manager) {
 }
 
 
+ThreadState::~ThreadState() {
+  DeleteArray<char>(data_);
+}
+
+
 void ThreadState::AllocateSpace() {
   data_ = NewArray<char>(ArchiveSpacePerThread());
 }
@@ -293,8 +243,7 @@
 // be distinguished from not having a thread id at all (since NULL is
 // defined as 0.)
 ThreadManager::ThreadManager()
-    : mutex_(OS::CreateMutex()),
-      mutex_owner_(ThreadId::Invalid()),
+    : mutex_owner_(ThreadId::Invalid()),
       lazily_archived_thread_(ThreadId::Invalid()),
       lazily_archived_thread_state_(NULL),
       free_anchor_(NULL),
@@ -305,16 +254,26 @@
 
 
 ThreadManager::~ThreadManager() {
-  delete mutex_;
-  delete free_anchor_;
-  delete in_use_anchor_;
+  DeleteThreadStateList(free_anchor_);
+  DeleteThreadStateList(in_use_anchor_);
+}
+
+
+void ThreadManager::DeleteThreadStateList(ThreadState* anchor) {
+  // The list starts and ends with the anchor.
+  for (ThreadState* current = anchor->next_; current != anchor;) {
+    ThreadState* next = current->next_;
+    delete current;
+    current = next;
+  }
+  delete anchor;
 }
 
 
 void ThreadManager::ArchiveThread() {
-  ASSERT(lazily_archived_thread_.Equals(ThreadId::Invalid()));
-  ASSERT(!IsArchived());
-  ASSERT(IsLockedByCurrentThread());
+  DCHECK(lazily_archived_thread_.Equals(ThreadId::Invalid()));
+  DCHECK(!IsArchived());
+  DCHECK(IsLockedByCurrentThread());
   ThreadState* state = GetFreeThreadState();
   state->Unlink();
   Isolate::PerIsolateThreadData* per_thread =
@@ -322,14 +281,14 @@
   per_thread->set_thread_state(state);
   lazily_archived_thread_ = ThreadId::Current();
   lazily_archived_thread_state_ = state;
-  ASSERT(state->id().Equals(ThreadId::Invalid()));
+  DCHECK(state->id().Equals(ThreadId::Invalid()));
   state->set_id(CurrentId());
-  ASSERT(!state->id().Equals(ThreadId::Invalid()));
+  DCHECK(!state->id().Equals(ThreadId::Invalid()));
 }
 
 
 void ThreadManager::EagerlyArchiveThread() {
-  ASSERT(IsLockedByCurrentThread());
+  DCHECK(IsLockedByCurrentThread());
   ThreadState* state = lazily_archived_thread_state_;
   state->LinkInto(ThreadState::IN_USE_LIST);
   char* to = state->data();
@@ -338,9 +297,7 @@
   to = isolate_->handle_scope_implementer()->ArchiveThread(to);
   to = isolate_->ArchiveThread(to);
   to = Relocatable::ArchiveState(isolate_, to);
-#ifdef ENABLE_DEBUGGER_SUPPORT
   to = isolate_->debug()->ArchiveDebug(to);
-#endif
   to = isolate_->stack_guard()->ArchiveStackGuard(to);
   to = isolate_->regexp_stack()->ArchiveStack(to);
   to = isolate_->bootstrapper()->ArchiveState(to);
@@ -350,11 +307,12 @@
 
 
 void ThreadManager::FreeThreadResources() {
+  DCHECK(!isolate_->has_pending_exception());
+  DCHECK(!isolate_->external_caught_exception());
+  DCHECK(isolate_->try_catch_handler() == NULL);
   isolate_->handle_scope_implementer()->FreeThreadResources();
   isolate_->FreeThreadResources();
-#ifdef ENABLE_DEBUGGER_SUPPORT
   isolate_->debug()->FreeThreadResources();
-#endif
   isolate_->stack_guard()->FreeThreadResources();
   isolate_->regexp_stack()->FreeThreadResources();
   isolate_->bootstrapper()->FreeThreadResources();
@@ -367,6 +325,7 @@
   return data != NULL && data->thread_state() != NULL;
 }
 
+
 void ThreadManager::Iterate(ObjectVisitor* v) {
   // Expecting no threads during serialization/deserialization
   for (ThreadState* state = FirstThreadStateInUse();
@@ -407,66 +366,5 @@
 }
 
 
-ContextSwitcher::ContextSwitcher(Isolate* isolate, int every_n_ms)
-  : Thread("v8:CtxtSwitcher"),
-    keep_going_(true),
-    sleep_ms_(every_n_ms),
-    isolate_(isolate) {
-}
-
-
-// Set the scheduling interval of V8 threads. This function starts the
-// ContextSwitcher thread if needed.
-void ContextSwitcher::StartPreemption(int every_n_ms) {
-  Isolate* isolate = Isolate::Current();
-  ASSERT(Locker::IsLocked(reinterpret_cast<v8::Isolate*>(isolate)));
-  if (isolate->context_switcher() == NULL) {
-    // If the ContextSwitcher thread is not running at the moment start it now.
-    isolate->set_context_switcher(new ContextSwitcher(isolate, every_n_ms));
-    isolate->context_switcher()->Start();
-  } else {
-    // ContextSwitcher thread is already running, so we just change the
-    // scheduling interval.
-    isolate->context_switcher()->sleep_ms_ = every_n_ms;
-  }
-}
-
-
-// Disable preemption of V8 threads. If multiple threads want to use V8 they
-// must cooperatively schedule amongst them from this point on.
-void ContextSwitcher::StopPreemption() {
-  Isolate* isolate = Isolate::Current();
-  ASSERT(Locker::IsLocked(reinterpret_cast<v8::Isolate*>(isolate)));
-  if (isolate->context_switcher() != NULL) {
-    // The ContextSwitcher thread is running. We need to stop it and release
-    // its resources.
-    isolate->context_switcher()->keep_going_ = false;
-    // Wait for the ContextSwitcher thread to exit.
-    isolate->context_switcher()->Join();
-    // Thread has exited, now we can delete it.
-    delete(isolate->context_switcher());
-    isolate->set_context_switcher(NULL);
-  }
-}
-
-
-// Main loop of the ContextSwitcher thread: Preempt the currently running V8
-// thread at regular intervals.
-void ContextSwitcher::Run() {
-  while (keep_going_) {
-    OS::Sleep(sleep_ms_);
-    isolate()->stack_guard()->Preempt();
-  }
-}
-
-
-// Acknowledge the preemption by the receiving thread.
-void ContextSwitcher::PreemptionReceived() {
-  ASSERT(Locker::IsLocked());
-  // There is currently no accounting being done for this. But could be in the
-  // future, which is why we leave this in.
-}
-
-
 }  // namespace internal
 }  // namespace v8