10040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Copyright 2007-2011 the V8 project authors. All rights reserved.
20040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Redistribution and use in source and binary forms, with or without
30040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// modification, are permitted provided that the following conditions are
40040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// met:
50040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org//
60040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org//     * Redistributions of source code must retain the above copyright
70040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org//       notice, this list of conditions and the following disclaimer.
80040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org//     * Redistributions in binary form must reproduce the above
90040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org//       copyright notice, this list of conditions and the following
100040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org//       disclaimer in the documentation and/or other materials provided
110040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org//       with the distribution.
120040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org//     * Neither the name of Google Inc. nor the names of its
130040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org//       contributors may be used to endorse or promote products derived
140040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org//       from this software without specific prior written permission.
150040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org//
160040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
170040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
180040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
190040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
200040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
210040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
220040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
230040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
240040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
250040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
260040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
270040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
280040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org#include <limits.h>
290040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
30196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
310040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
32196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/api.h"
335de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/platform.h"
34196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compilation-cache.h"
35196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/execution.h"
36196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate.h"
37196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/parser.h"
38196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/smart-pointers.h"
39196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/snapshot.h"
40196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/unicode-inl.h"
41196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/utils.h"
42196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "test/cctest/cctest.h"
430040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
440040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::Context;
450040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::Extension;
460040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::Function;
470040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::HandleScope;
480040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::Local;
490040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::Object;
500040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::ObjectTemplate;
510040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::Persistent;
520040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::Script;
530040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::String;
540040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::Value;
550040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgusing ::v8::V8;
560040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
570040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
580040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Migrating an isolate
595de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgclass KangarooThread : public v8::base::Thread {
600040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
61ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  KangarooThread(v8::Isolate* isolate, v8::Handle<v8::Context> context)
625e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      : Thread(Options("KangarooThread")),
63ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        isolate_(isolate),
64ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        context_(isolate, context) {}
650040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
660040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  void Run() {
670040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
680040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Locker locker(isolate_);
690040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Isolate::Scope isolate_scope(isolate_);
700040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CHECK_EQ(isolate_, v8::internal::Isolate::Current());
712bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      v8::HandleScope scope(isolate_);
72c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      v8::Local<v8::Context> context =
73c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org          v8::Local<v8::Context>::New(isolate_, context_);
74c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      v8::Context::Scope context_scope(context);
750040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      Local<Value> v = CompileRun("getValue()");
760040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CHECK(v->IsNumber());
770040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CHECK_EQ(30, static_cast<int>(v->NumberValue()));
780040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
790040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
800040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Locker locker(isolate_);
810040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Isolate::Scope isolate_scope(isolate_);
822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      v8::HandleScope scope(isolate_);
83c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      v8::Local<v8::Context> context =
84c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org          v8::Local<v8::Context>::New(isolate_, context_);
85c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      v8::Context::Scope context_scope(context);
860040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      Local<Value> v = CompileRun("getValue()");
870040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CHECK(v->IsNumber());
880040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CHECK_EQ(30, static_cast<int>(v->NumberValue()));
890040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
900040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    isolate_->Dispose();
910040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
920040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
930040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
940040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate_;
950040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  Persistent<v8::Context> context_;
960040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
970040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
98e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
990040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Migrates an isolate from one thread to another
1000040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgTEST(KangarooIsolates) {
1010040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate = v8::Isolate::New();
102ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  i::SmartPointer<KangarooThread> thread1;
1030040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  {
1040040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Locker locker(isolate);
1050040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Isolate::Scope isolate_scope(isolate);
1062bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    v8::HandleScope handle_scope(isolate);
107ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    v8::Local<v8::Context> context = v8::Context::New(isolate);
1080040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Context::Scope context_scope(context);
1090040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    CHECK_EQ(isolate, v8::internal::Isolate::Current());
1100040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    CompileRun("function getValue() { return 30; }");
111ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    thread1.Reset(new KangarooThread(isolate, context));
1120040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
113ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  thread1->Start();
114ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  thread1->Join();
1150040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
1160040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
117e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1180040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgstatic void CalcFibAndCheck() {
1190040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  Local<Value> v = CompileRun("function fib(n) {"
1200040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org                              "  if (n <= 2) return 1;"
1210040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org                              "  return fib(n-1) + fib(n-2);"
1220040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org                              "}"
1230040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org                              "fib(10)");
1240040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  CHECK(v->IsNumber());
1250040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  CHECK_EQ(55, static_cast<int>(v->NumberValue()));
1260040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
1270040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1280040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgclass JoinableThread {
1290040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
1300040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  explicit JoinableThread(const char* name)
1310040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    : name_(name),
132e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      semaphore_(0),
1330040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      thread_(this) {
1340040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
1350040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
136e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org  virtual ~JoinableThread() {}
1370040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1380040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  void Start() {
1390040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    thread_.Start();
1400040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
1410040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1420040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  void Join() {
143e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org    semaphore_.Wait();
1440040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
1450040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1460040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  virtual void Run() = 0;
14783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org
1480040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
1495de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  class ThreadWithSemaphore : public v8::base::Thread {
1500040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org   public:
1510040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    explicit ThreadWithSemaphore(JoinableThread* joinable_thread)
1525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        : Thread(Options(joinable_thread->name_)),
1535e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          joinable_thread_(joinable_thread) {}
1540040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1550040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    virtual void Run() {
1560040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      joinable_thread_->Run();
157e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org      joinable_thread_->semaphore_.Signal();
1580040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
1590040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1600040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org   private:
1610040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    JoinableThread* joinable_thread_;
1620040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  };
1630040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1640040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  const char* name_;
1655de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  v8::base::Semaphore semaphore_;
1660040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  ThreadWithSemaphore thread_;
1670040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1680040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  friend class ThreadWithSemaphore;
1690040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1700040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  DISALLOW_COPY_AND_ASSIGN(JoinableThread);
1710040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
1720040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1730040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1740040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgclass IsolateLockingThreadWithLocalContext : public JoinableThread {
1750040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
1760040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  explicit IsolateLockingThreadWithLocalContext(v8::Isolate* isolate)
1770040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    : JoinableThread("IsolateLockingThread"),
1780040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      isolate_(isolate) {
1790040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
1800040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
1810040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  virtual void Run() {
1820040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Locker locker(isolate_);
1830040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Isolate::Scope isolate_scope(isolate_);
1842bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    v8::HandleScope handle_scope(isolate_);
185528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    LocalContext local_context(isolate_);
1860040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    CHECK_EQ(isolate_, v8::internal::Isolate::Current());
1870040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    CalcFibAndCheck();
1880040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
1890040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
1900040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate_;
1910040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
1920040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
193e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1940040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgstatic void StartJoinAndDeleteThreads(const i::List<JoinableThread*>& threads) {
1950040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  for (int i = 0; i < threads.length(); i++) {
1960040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    threads[i]->Start();
1970040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
1980040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  for (int i = 0; i < threads.length(); i++) {
1990040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    threads[i]->Join();
2000040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
2010040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  for (int i = 0; i < threads.length(); i++) {
2020040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    delete threads[i];
2030040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
2040040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
2050040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
2060040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
2070040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Run many threads all locking on the same isolate
2080040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgTEST(IsolateLockingStress) {
20993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS
210f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  const int kNThreads = 50;
211f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org#else
2120040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  const int kNThreads = 100;
213f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org#endif
2140040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  i::List<JoinableThread*> threads(kNThreads);
2150040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate = v8::Isolate::New();
2160040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  for (int i = 0; i < kNThreads; i++) {
2170040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    threads.Add(new IsolateLockingThreadWithLocalContext(isolate));
2180040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
2190040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  StartJoinAndDeleteThreads(threads);
2200040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  isolate->Dispose();
2210040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
2220040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
2230040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgclass IsolateNonlockingThread : public JoinableThread {
2240040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
2255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  IsolateNonlockingThread() : JoinableThread("IsolateNonlockingThread") {}
2260040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
2270040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  virtual void Run() {
2280040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Isolate* isolate = v8::Isolate::New();
2290040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
2300040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Isolate::Scope isolate_scope(isolate);
2312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      v8::HandleScope handle_scope(isolate);
23257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      v8::Handle<v8::Context> context = v8::Context::New(isolate);
2330040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Context::Scope context_scope(context);
2340040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CHECK_EQ(isolate, v8::internal::Isolate::Current());
2350040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CalcFibAndCheck();
2360040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
2370040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    isolate->Dispose();
2380040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
2390040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
2400040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
2410040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
242e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
2430040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Run many threads each accessing its own isolate without locking
2440040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgTEST(MultithreadedParallelIsolates) {
24593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
2467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  const int kNThreads = 10;
24708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
24808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const int kNThreads = 4;
2497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#else
2500040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  const int kNThreads = 50;
2517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#endif
2520040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  i::List<JoinableThread*> threads(kNThreads);
2530040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  for (int i = 0; i < kNThreads; i++) {
2540040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    threads.Add(new IsolateNonlockingThread());
2550040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
2560040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  StartJoinAndDeleteThreads(threads);
2570040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
2580040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
2590040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
2600040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgclass IsolateNestedLockingThread : public JoinableThread {
2610040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
2620040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  explicit IsolateNestedLockingThread(v8::Isolate* isolate)
2630040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    : JoinableThread("IsolateNestedLocking"), isolate_(isolate) {
2640040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
2650040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  virtual void Run() {
2660040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Locker lock(isolate_);
2670040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Isolate::Scope isolate_scope(isolate_);
2682bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    v8::HandleScope handle_scope(isolate_);
269528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    LocalContext local_context(isolate_);
2700040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
2710040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Locker another_lock(isolate_);
2720040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CalcFibAndCheck();
2730040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
2740040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
2750040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Locker another_lock(isolate_);
2760040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CalcFibAndCheck();
2770040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
2780040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
2790040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
2800040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate_;
2810040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
2820040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
283e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
2840040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Run  many threads with nested locks
2850040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgTEST(IsolateNestedLocking) {
28693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS
287f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  const int kNThreads = 50;
288f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org#else
2890040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  const int kNThreads = 100;
290f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org#endif
2910040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate = v8::Isolate::New();
2920040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  i::List<JoinableThread*> threads(kNThreads);
2930040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  for (int i = 0; i < kNThreads; i++) {
2940040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    threads.Add(new IsolateNestedLockingThread(isolate));
2950040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
2960040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  StartJoinAndDeleteThreads(threads);
2977c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  isolate->Dispose();
2980040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
2990040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
3000040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
3010040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgclass SeparateIsolatesLocksNonexclusiveThread : public JoinableThread {
3020040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
3030040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  SeparateIsolatesLocksNonexclusiveThread(v8::Isolate* isolate1,
3040040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org                                          v8::Isolate* isolate2)
3050040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    : JoinableThread("SeparateIsolatesLocksNonexclusiveThread"),
3060040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      isolate1_(isolate1), isolate2_(isolate2) {
3070040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
3080040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
3090040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  virtual void Run() {
3100040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Locker lock(isolate1_);
3110040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Isolate::Scope isolate_scope(isolate1_);
3122bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    v8::HandleScope handle_scope(isolate1_);
313528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    LocalContext local_context(isolate1_);
3140040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
3150040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    IsolateLockingThreadWithLocalContext threadB(isolate2_);
3160040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    threadB.Start();
3170040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    CalcFibAndCheck();
3180040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    threadB.Join();
3190040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
3200040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
3210040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate1_;
3220040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate2_;
3230040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
3240040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
325e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
3260040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Run parallel threads that lock and access different isolates in parallel
3270040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgTEST(SeparateIsolatesLocksNonexclusive) {
32893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
329030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  const int kNThreads = 50;
330030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#else
3310040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  const int kNThreads = 100;
332030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#endif
3330040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate1 = v8::Isolate::New();
3340040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate2 = v8::Isolate::New();
3350040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  i::List<JoinableThread*> threads(kNThreads);
3360040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  for (int i = 0; i < kNThreads; i++) {
3370040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    threads.Add(new SeparateIsolatesLocksNonexclusiveThread(isolate1,
3380040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org                                                             isolate2));
3390040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
3400040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  StartJoinAndDeleteThreads(threads);
3410040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  isolate2->Dispose();
3420040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  isolate1->Dispose();
3430040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
3440040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
3450040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgclass LockIsolateAndCalculateFibSharedContextThread : public JoinableThread {
3460040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
3470040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  explicit LockIsolateAndCalculateFibSharedContextThread(
3480040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Isolate* isolate, v8::Handle<v8::Context> context)
3490040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    : JoinableThread("LockIsolateAndCalculateFibThread"),
3500040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      isolate_(isolate),
351ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      context_(isolate, context) {
3520040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
3530040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
3540040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  virtual void Run() {
3550040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Locker lock(isolate_);
3560040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Isolate::Scope isolate_scope(isolate_);
3572bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    HandleScope handle_scope(isolate_);
358c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    v8::Local<v8::Context> context =
359c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org        v8::Local<v8::Context>::New(isolate_, context_);
360c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org    v8::Context::Scope context_scope(context);
3610040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    CalcFibAndCheck();
3620040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
3630040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
3640040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate_;
3650040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  Persistent<v8::Context> context_;
3660040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
3670040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
3680040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgclass LockerUnlockerThread : public JoinableThread {
3690040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
3700040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  explicit LockerUnlockerThread(v8::Isolate* isolate)
3710040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    : JoinableThread("LockerUnlockerThread"),
3720040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      isolate_(isolate) {
3730040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
3740040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
3750040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  virtual void Run() {
3760040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Locker lock(isolate_);
3770040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Isolate::Scope isolate_scope(isolate_);
3782bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    v8::HandleScope handle_scope(isolate_);
379ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    v8::Local<v8::Context> context = v8::Context::New(isolate_);
3800040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
3810040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Context::Scope context_scope(context);
3820040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CalcFibAndCheck();
3830040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
3840040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
385ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      LockIsolateAndCalculateFibSharedContextThread thread(isolate_, context);
3860040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      isolate_->Exit();
3870040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Unlocker unlocker(isolate_);
3880040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      thread.Start();
3890040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      thread.Join();
3900040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
3910040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    isolate_->Enter();
3920040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
3930040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Context::Scope context_scope(context);
3940040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CalcFibAndCheck();
3950040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
3960040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
39783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org
3980040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
3990040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate_;
4000040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
4010040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
402e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
4030040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Use unlocker inside of a Locker, multiple threads.
4040040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgTEST(LockerUnlocker) {
40593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
406030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  const int kNThreads = 50;
407030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#else
4080040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  const int kNThreads = 100;
409030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#endif
4100040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  i::List<JoinableThread*> threads(kNThreads);
4110040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate = v8::Isolate::New();
4120040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  for (int i = 0; i < kNThreads; i++) {
4130040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    threads.Add(new LockerUnlockerThread(isolate));
4140040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
4150040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  StartJoinAndDeleteThreads(threads);
4160040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  isolate->Dispose();
4170040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
4180040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
4190040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgclass LockTwiceAndUnlockThread : public JoinableThread {
4200040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
4210040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  explicit LockTwiceAndUnlockThread(v8::Isolate* isolate)
4220040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    : JoinableThread("LockTwiceAndUnlockThread"),
4230040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      isolate_(isolate) {
4240040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
4250040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
4260040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  virtual void Run() {
4270040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Locker lock(isolate_);
4280040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Isolate::Scope isolate_scope(isolate_);
4292bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    v8::HandleScope handle_scope(isolate_);
430ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    v8::Local<v8::Context> context = v8::Context::New(isolate_);
4310040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
4320040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Context::Scope context_scope(context);
4330040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CalcFibAndCheck();
4340040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
4350040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
4360040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Locker second_lock(isolate_);
4370040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      {
438ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        LockIsolateAndCalculateFibSharedContextThread thread(isolate_, context);
4390040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        isolate_->Exit();
4400040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        v8::Unlocker unlocker(isolate_);
4410040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        thread.Start();
4420040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        thread.Join();
4430040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      }
4440040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
4450040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    isolate_->Enter();
4460040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
4470040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Context::Scope context_scope(context);
4480040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CalcFibAndCheck();
4490040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
4500040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
45183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org
4520040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
4530040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate_;
4540040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
4550040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
456e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
4570040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Use Unlocker inside two Lockers.
4580040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgTEST(LockTwiceAndUnlock) {
45993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
460030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  const int kNThreads = 50;
461030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#else
4620040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  const int kNThreads = 100;
463030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#endif
4640040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  i::List<JoinableThread*> threads(kNThreads);
4650040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate = v8::Isolate::New();
4660040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  for (int i = 0; i < kNThreads; i++) {
4670040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    threads.Add(new LockTwiceAndUnlockThread(isolate));
4680040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
4690040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  StartJoinAndDeleteThreads(threads);
4700040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  isolate->Dispose();
4710040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
4720040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
4730040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgclass LockAndUnlockDifferentIsolatesThread : public JoinableThread {
4740040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
4750040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  LockAndUnlockDifferentIsolatesThread(v8::Isolate* isolate1,
4760040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org                                       v8::Isolate* isolate2)
4770040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    : JoinableThread("LockAndUnlockDifferentIsolatesThread"),
4780040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      isolate1_(isolate1),
4790040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      isolate2_(isolate2) {
4800040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
4810040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
4820040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  virtual void Run() {
48357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    i::SmartPointer<LockIsolateAndCalculateFibSharedContextThread> thread;
4840040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Locker lock1(isolate1_);
4850040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    CHECK(v8::Locker::IsLocked(isolate1_));
4860040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    CHECK(!v8::Locker::IsLocked(isolate2_));
4870040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
4880040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Isolate::Scope isolate_scope(isolate1_);
4892bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      v8::HandleScope handle_scope(isolate1_);
49057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      v8::Handle<v8::Context> context1 = v8::Context::New(isolate1_);
4910040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      {
4920040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        v8::Context::Scope context_scope(context1);
4930040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        CalcFibAndCheck();
4940040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      }
49557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      thread.Reset(new LockIsolateAndCalculateFibSharedContextThread(
49657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          isolate1_, context1));
4970040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
4980040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Locker lock2(isolate2_);
4990040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    CHECK(v8::Locker::IsLocked(isolate1_));
5000040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    CHECK(v8::Locker::IsLocked(isolate2_));
5010040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
5020040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Isolate::Scope isolate_scope(isolate2_);
5032bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      v8::HandleScope handle_scope(isolate2_);
50457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      v8::Handle<v8::Context> context2 = v8::Context::New(isolate2_);
5050040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      {
5060040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        v8::Context::Scope context_scope(context2);
5070040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        CalcFibAndCheck();
5080040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      }
5090040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Unlocker unlock1(isolate1_);
5100040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CHECK(!v8::Locker::IsLocked(isolate1_));
5110040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CHECK(v8::Locker::IsLocked(isolate2_));
5120040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Context::Scope context_scope(context2);
513ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      thread->Start();
5140040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CalcFibAndCheck();
515ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      thread->Join();
5160040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
5170040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
51883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org
5190040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
5200040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate1_;
5210040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate2_;
5220040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
5230040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
524e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
5250040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Lock two isolates and unlock one of them.
5260040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgTEST(LockAndUnlockDifferentIsolates) {
5270040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate1 = v8::Isolate::New();
5280040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate2 = v8::Isolate::New();
5290040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  LockAndUnlockDifferentIsolatesThread thread(isolate1, isolate2);
5300040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  thread.Start();
5310040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  thread.Join();
5320040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  isolate2->Dispose();
5330040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  isolate1->Dispose();
5340040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
5350040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
5360040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgclass LockUnlockLockThread : public JoinableThread {
5370040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
53857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  LockUnlockLockThread(v8::Isolate* isolate, v8::Handle<v8::Context> context)
5390040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    : JoinableThread("LockUnlockLockThread"),
5400040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      isolate_(isolate),
541ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      context_(isolate, context) {
5420040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
5430040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
5440040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  virtual void Run() {
5450040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Locker lock1(isolate_);
5460040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    CHECK(v8::Locker::IsLocked(isolate_));
547528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    CHECK(!v8::Locker::IsLocked(CcTest::isolate()));
5480040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
5490040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Isolate::Scope isolate_scope(isolate_);
5502bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      v8::HandleScope handle_scope(isolate_);
551c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      v8::Local<v8::Context> context =
552c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org          v8::Local<v8::Context>::New(isolate_, context_);
553c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      v8::Context::Scope context_scope(context);
5540040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CalcFibAndCheck();
5550040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
5560040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
5570040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      v8::Unlocker unlock1(isolate_);
5580040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CHECK(!v8::Locker::IsLocked(isolate_));
559528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      CHECK(!v8::Locker::IsLocked(CcTest::isolate()));
5600040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      {
5610040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        v8::Locker lock2(isolate_);
5620040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        v8::Isolate::Scope isolate_scope(isolate_);
5632bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org        v8::HandleScope handle_scope(isolate_);
5640040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        CHECK(v8::Locker::IsLocked(isolate_));
565528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        CHECK(!v8::Locker::IsLocked(CcTest::isolate()));
566c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org        v8::Local<v8::Context> context =
567c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org            v8::Local<v8::Context>::New(isolate_, context_);
568c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org        v8::Context::Scope context_scope(context);
5690040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        CalcFibAndCheck();
5700040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      }
5710040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
5720040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
5730040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
5740040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
5750040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate_;
5760040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Persistent<v8::Context> context_;
5770040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
5780040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
579e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
5800040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Locker inside an Unlocker inside a Locker.
5810040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgTEST(LockUnlockLockMultithreaded) {
58293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS
583f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  const int kNThreads = 50;
584f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org#else
5850040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  const int kNThreads = 100;
586f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org#endif
5870040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Isolate* isolate = v8::Isolate::New();
588ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  i::List<JoinableThread*> threads(kNThreads);
5890040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  {
5900040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Locker locker_(isolate);
5910040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    v8::Isolate::Scope isolate_scope(isolate);
5922bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    v8::HandleScope handle_scope(isolate);
59357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    v8::Handle<v8::Context> context = v8::Context::New(isolate);
594ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    for (int i = 0; i < kNThreads; i++) {
595ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      threads.Add(new LockUnlockLockThread(
59657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          isolate, context));
597ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    }
5980040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
5990040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  StartJoinAndDeleteThreads(threads);
6007c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  isolate->Dispose();
6010040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
6020040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
6030040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgclass LockUnlockLockDefaultIsolateThread : public JoinableThread {
6040040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org public:
60557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  explicit LockUnlockLockDefaultIsolateThread(v8::Handle<v8::Context> context)
606ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      : JoinableThread("LockUnlockLockDefaultIsolateThread"),
607528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        context_(CcTest::isolate(), context) {}
6080040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
6090040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  virtual void Run() {
610528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    v8::Locker lock1(CcTest::isolate());
6110040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
612528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      v8::Isolate::Scope isolate_scope(CcTest::isolate());
613528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      v8::HandleScope handle_scope(CcTest::isolate());
614c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      v8::Local<v8::Context> context =
615528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          v8::Local<v8::Context>::New(CcTest::isolate(), context_);
616c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org      v8::Context::Scope context_scope(context);
6170040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      CalcFibAndCheck();
6180040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
6190040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    {
620528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      v8::Unlocker unlock1(CcTest::isolate());
6210040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      {
622528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        v8::Locker lock2(CcTest::isolate());
623528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        v8::Isolate::Scope isolate_scope(CcTest::isolate());
624528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        v8::HandleScope handle_scope(CcTest::isolate());
625c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org        v8::Local<v8::Context> context =
626528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org            v8::Local<v8::Context>::New(CcTest::isolate(), context_);
627c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org        v8::Context::Scope context_scope(context);
6280040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org        CalcFibAndCheck();
6290040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org      }
6300040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org    }
6310040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
6320040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
6330040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org private:
6340040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  v8::Persistent<v8::Context> context_;
6350040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org};
6360040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org
637e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
6380040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org// Locker inside an Unlocker inside a Locker for default isolate.
6390040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.orgTEST(LockUnlockLockDefaultIsolateMultithreaded) {
64093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS
641f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  const int kNThreads = 50;
642f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org#else
6430040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  const int kNThreads = 100;
644f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org#endif
64557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  Local<v8::Context> context;
646ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  i::List<JoinableThread*> threads(kNThreads);
6470040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  {
648528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    v8::Locker locker_(CcTest::isolate());
649528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    v8::Isolate::Scope isolate_scope(CcTest::isolate());
650528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    v8::HandleScope handle_scope(CcTest::isolate());
651528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    context = v8::Context::New(CcTest::isolate());
652ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    for (int i = 0; i < kNThreads; i++) {
65357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      threads.Add(new LockUnlockLockDefaultIsolateThread(context));
654ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    }
6550040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  }
6560040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org  StartJoinAndDeleteThreads(threads);
6570040ca93e7ca9c0968f7bc27088ce045cb32c402lrn@chromium.org}
658e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
659e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
660e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgTEST(Regress1433) {
661e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  for (int i = 0; i < 10; i++) {
662e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    v8::Isolate* isolate = v8::Isolate::New();
663e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    {
664e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      v8::Locker lock(isolate);
665e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      v8::Isolate::Scope isolate_scope(isolate);
6662bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      v8::HandleScope handle_scope(isolate);
66757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      v8::Handle<Context> context = v8::Context::New(isolate);
668e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      v8::Context::Scope context_scope(context);
669f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      v8::Handle<String> source = v8::String::NewFromUtf8(isolate, "1+1");
670e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      v8::Handle<Script> script = v8::Script::Compile(source);
671e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org      v8::Handle<Value> result = script->Run();
672906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org      v8::String::Utf8Value utf8(result);
673e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    }
674e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org    isolate->Dispose();
675e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  }
676e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org}
67727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
67827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
67927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgstatic const char* kSimpleExtensionSource =
68027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  "(function Foo() {"
68127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  "  return 4;"
68227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  "})() ";
68327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
68427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgclass IsolateGenesisThread : public JoinableThread {
68527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org public:
68627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  IsolateGenesisThread(int count, const char* extension_names[])
68727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    : JoinableThread("IsolateGenesisThread"),
68827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      count_(count),
68927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      extension_names_(extension_names)
69027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  {}
69127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
69227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  virtual void Run() {
69327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    v8::Isolate* isolate = v8::Isolate::New();
69427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    {
69527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      v8::Isolate::Scope isolate_scope(isolate);
69627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      CHECK(!i::Isolate::Current()->has_installed_extensions());
69727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      v8::ExtensionConfiguration extensions(count_, extension_names_);
69857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      v8::HandleScope handle_scope(isolate);
69957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      v8::Context::New(isolate, &extensions);
70027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org      CHECK(i::Isolate::Current()->has_installed_extensions());
70127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    }
70227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    isolate->Dispose();
70327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  }
70427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org private:
70527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  int count_;
70627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  const char** extension_names_;
70727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org};
70827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org
709e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
71027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org// Test installing extensions in separate isolates concurrently.
71127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org// http://code.google.com/p/v8/issues/detail?id=1821
71227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.orgTEST(ExtensionsRegistration) {
71393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
714f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  const int kNThreads = 10;
71508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
71608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const int kNThreads = 4;
717f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org#else
71827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  const int kNThreads = 40;
719f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org#endif
72027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  v8::RegisterExtension(new v8::Extension("test0",
72127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                          kSimpleExtensionSource));
72227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  v8::RegisterExtension(new v8::Extension("test1",
72327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                          kSimpleExtensionSource));
72427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  v8::RegisterExtension(new v8::Extension("test2",
72527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                          kSimpleExtensionSource));
72627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  v8::RegisterExtension(new v8::Extension("test3",
72727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                          kSimpleExtensionSource));
72827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  v8::RegisterExtension(new v8::Extension("test4",
72927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                          kSimpleExtensionSource));
73027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  v8::RegisterExtension(new v8::Extension("test5",
73127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                          kSimpleExtensionSource));
73227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  v8::RegisterExtension(new v8::Extension("test6",
73327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                          kSimpleExtensionSource));
73427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  v8::RegisterExtension(new v8::Extension("test7",
73527bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                          kSimpleExtensionSource));
73627bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  const char* extension_names[] = { "test0", "test1",
73727bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                    "test2", "test3", "test4",
73827bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org                                    "test5", "test6", "test7" };
73927bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  i::List<JoinableThread*> threads(kNThreads);
74027bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  for (int i = 0; i < kNThreads; i++) {
74127bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org    threads.Add(new IsolateGenesisThread(8, extension_names));
74227bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  }
74327bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org  StartJoinAndDeleteThreads(threads);
74427bf28851c1fa362a3f7c709871c21dcc9c23ce7ricow@chromium.org}
745