1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2007-2011 the V8 project authors. All rights reserved.
2257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Redistribution and use in source and binary forms, with or without
3257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// modification, are permitted provided that the following conditions are
4257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// met:
5257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//
6257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//     * Redistributions of source code must retain the above copyright
7257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//       notice, this list of conditions and the following disclaimer.
8257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//     * Redistributions in binary form must reproduce the above
9257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//       copyright notice, this list of conditions and the following
10257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//       disclaimer in the documentation and/or other materials provided
11257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//       with the distribution.
12257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//     * Neither the name of Google Inc. nor the names of its
13257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//       contributors may be used to endorse or promote products derived
14257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//       from this software without specific prior written permission.
15257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//
16257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
28257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include <limits.h>
29257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
30257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "v8.h"
31257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
32257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "api.h"
33257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "isolate.h"
34257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "compilation-cache.h"
35257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "execution.h"
36257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "snapshot.h"
37257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "platform.h"
38257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "utils.h"
39257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "cctest.h"
40257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "parser.h"
41257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "unicode-inl.h"
42257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
43257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::AccessorInfo;
44257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::Context;
45257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::Extension;
46257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::Function;
47257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::HandleScope;
48257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::Local;
49257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::Object;
50257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::ObjectTemplate;
51257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::Persistent;
52257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::Script;
53257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::String;
54257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::Value;
55257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochusing ::v8::V8;
56257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
57257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
58257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Migrating an isolate
59257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass KangarooThread : public v8::internal::Thread {
60257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
61257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  KangarooThread(v8::Isolate* isolate,
62257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                 v8::Handle<v8::Context> context, int value)
633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      : Thread("KangarooThread"),
64257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        isolate_(isolate), context_(context), value_(value) {
65257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
66257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
67257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void Run() {
68257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
69257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Locker locker(isolate_);
70257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Isolate::Scope isolate_scope(isolate_);
71257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CHECK_EQ(isolate_, v8::internal::Isolate::Current());
72257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::HandleScope scope;
73257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Context::Scope context_scope(context_);
74257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Local<Value> v = CompileRun("getValue()");
75257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CHECK(v->IsNumber());
76257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CHECK_EQ(30, static_cast<int>(v->NumberValue()));
77257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
78257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
79257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Locker locker(isolate_);
80257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Isolate::Scope isolate_scope(isolate_);
81257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Context::Scope context_scope(context_);
82257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::HandleScope scope;
83257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Local<Value> v = CompileRun("getValue()");
84257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CHECK(v->IsNumber());
85257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CHECK_EQ(30, static_cast<int>(v->NumberValue()));
86257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
87257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    isolate_->Dispose();
88257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
89257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
90257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
91257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate_;
92257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Persistent<v8::Context> context_;
93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int value_;
94257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
95257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
96257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Migrates an isolate from one thread to another
97257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(KangarooIsolates) {
98257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate = v8::Isolate::New();
99257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Persistent<v8::Context> context;
100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  {
101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker locker(isolate);
102257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Isolate::Scope isolate_scope(isolate);
103257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::HandleScope handle_scope;
104257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    context = v8::Context::New();
105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Context::Scope context_scope(context);
106257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CHECK_EQ(isolate, v8::internal::Isolate::Current());
107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CompileRun("function getValue() { return 30; }");
108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  KangarooThread thread1(isolate, context, 1);
110257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread1.Start();
111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread1.Join();
112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
114257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic void CalcFibAndCheck() {
115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Local<Value> v = CompileRun("function fib(n) {"
116257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                              "  if (n <= 2) return 1;"
117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                              "  return fib(n-1) + fib(n-2);"
118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                              "}"
119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                              "fib(10)");
120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  CHECK(v->IsNumber());
121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  CHECK_EQ(55, static_cast<int>(v->NumberValue()));
122257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
123257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
124257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass JoinableThread {
125257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit JoinableThread(const char* name)
127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    : name_(name),
128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      semaphore_(i::OS::CreateSemaphore(0)),
129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      thread_(this) {
130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual ~JoinableThread() {
133257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    delete semaphore_;
134257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
135257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
136257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void Start() {
137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    thread_.Start();
138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
139257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void Join() {
141257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    semaphore_->Wait();
142257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
143257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void Run() = 0;
145589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
147257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  class ThreadWithSemaphore : public i::Thread {
148257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch   public:
149257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    explicit ThreadWithSemaphore(JoinableThread* joinable_thread)
1503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      : Thread(joinable_thread->name_),
151257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        joinable_thread_(joinable_thread) {
152257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
153257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    virtual void Run() {
155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      joinable_thread_->Run();
156257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      joinable_thread_->semaphore_->Signal();
157257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
158257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
159257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch   private:
160257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JoinableThread* joinable_thread_;
161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  };
162257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
163257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const char* name_;
164257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Semaphore* semaphore_;
165257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ThreadWithSemaphore thread_;
166257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
167257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  friend class ThreadWithSemaphore;
168257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
169257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(JoinableThread);
170257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
171257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
172257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
173257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass IsolateLockingThreadWithLocalContext : public JoinableThread {
174257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
175257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit IsolateLockingThreadWithLocalContext(v8::Isolate* isolate)
176257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    : JoinableThread("IsolateLockingThread"),
177257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      isolate_(isolate) {
178257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
179257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
180257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void Run() {
181257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker locker(isolate_);
182257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Isolate::Scope isolate_scope(isolate_);
183257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::HandleScope handle_scope;
184257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    LocalContext local_context;
185257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CHECK_EQ(isolate_, v8::internal::Isolate::Current());
186257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CalcFibAndCheck();
187257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
188257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
189257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate_;
190257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
191257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
192257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic void StartJoinAndDeleteThreads(const i::List<JoinableThread*>& threads) {
193257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; i < threads.length(); i++) {
194257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threads[i]->Start();
195257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
196257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; i < threads.length(); i++) {
197257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threads[i]->Join();
198257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
199257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; i < threads.length(); i++) {
200257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    delete threads[i];
201257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
202257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
204257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
205257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Run many threads all locking on the same isolate
206257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(IsolateLockingStress) {
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef V8_TARGET_ARCH_MIPS
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const int kNThreads = 50;
2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#else
210257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const int kNThreads = 100;
2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
212257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::List<JoinableThread*> threads(kNThreads);
213257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate = v8::Isolate::New();
214257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; i < kNThreads; i++) {
215257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threads.Add(new IsolateLockingThreadWithLocalContext(isolate));
216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
217257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StartJoinAndDeleteThreads(threads);
218257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  isolate->Dispose();
219257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
220257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
221257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass IsolateNonlockingThread : public JoinableThread {
222257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
223257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit IsolateNonlockingThread()
224257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    : JoinableThread("IsolateNonlockingThread") {
225257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
227257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void Run() {
228257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Isolate* isolate = v8::Isolate::New();
229257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Isolate::Scope isolate_scope(isolate);
231257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::HandleScope handle_scope;
232257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Handle<v8::Context> context = v8::Context::New();
233257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Context::Scope context_scope(context);
234257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CHECK_EQ(isolate, v8::internal::Isolate::Current());
235257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CalcFibAndCheck();
236257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
237257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    isolate->Dispose();
238257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
239257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
240257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
241257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
242257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Run many threads each accessing its own isolate without locking
243257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(MultithreadedParallelIsolates) {
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
245257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const int kNThreads = 10;
246257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#else
247257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const int kNThreads = 50;
248257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
249257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::List<JoinableThread*> threads(kNThreads);
250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; i < kNThreads; i++) {
251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threads.Add(new IsolateNonlockingThread());
252257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
253257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StartJoinAndDeleteThreads(threads);
254257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
255257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
256257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
257257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass IsolateNestedLockingThread : public JoinableThread {
258257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
259257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit IsolateNestedLockingThread(v8::Isolate* isolate)
260257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    : JoinableThread("IsolateNestedLocking"), isolate_(isolate) {
261257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
262257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void Run() {
263257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker lock(isolate_);
264257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Isolate::Scope isolate_scope(isolate_);
265257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::HandleScope handle_scope;
266257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    LocalContext local_context;
267257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
268257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Locker another_lock(isolate_);
269257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CalcFibAndCheck();
270257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Locker another_lock(isolate_);
273257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CalcFibAndCheck();
274257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
275257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
276257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
277257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate_;
278257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
280257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Run  many threads with nested locks
281257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(IsolateNestedLocking) {
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef V8_TARGET_ARCH_MIPS
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const int kNThreads = 50;
2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#else
285257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const int kNThreads = 100;
2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate = v8::Isolate::New();
288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::List<JoinableThread*> threads(kNThreads);
289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; i < kNThreads; i++) {
290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threads.Add(new IsolateNestedLockingThread(isolate));
291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
292257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StartJoinAndDeleteThreads(threads);
293257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
295257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
296257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass SeparateIsolatesLocksNonexclusiveThread : public JoinableThread {
297257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
298257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  SeparateIsolatesLocksNonexclusiveThread(v8::Isolate* isolate1,
299257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                          v8::Isolate* isolate2)
300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    : JoinableThread("SeparateIsolatesLocksNonexclusiveThread"),
301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      isolate1_(isolate1), isolate2_(isolate2) {
302257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void Run() {
305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker lock(isolate1_);
306257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Isolate::Scope isolate_scope(isolate1_);
307257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::HandleScope handle_scope;
308257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    LocalContext local_context;
309257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
310257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    IsolateLockingThreadWithLocalContext threadB(isolate2_);
311257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threadB.Start();
312257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CalcFibAndCheck();
313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threadB.Join();
314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
316257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate1_;
317257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate2_;
318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
319257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
320257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Run parallel threads that lock and access different isolates in parallel
321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(SeparateIsolatesLocksNonexclusive) {
3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
3233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  const int kNThreads = 50;
3243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else
325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const int kNThreads = 100;
3263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
327257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate1 = v8::Isolate::New();
328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate2 = v8::Isolate::New();
329257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::List<JoinableThread*> threads(kNThreads);
330257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; i < kNThreads; i++) {
331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threads.Add(new SeparateIsolatesLocksNonexclusiveThread(isolate1,
332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                                             isolate2));
333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StartJoinAndDeleteThreads(threads);
335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  isolate2->Dispose();
336257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  isolate1->Dispose();
337257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass LockIsolateAndCalculateFibSharedContextThread : public JoinableThread {
340257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
341257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit LockIsolateAndCalculateFibSharedContextThread(
342257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Isolate* isolate, v8::Handle<v8::Context> context)
343257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    : JoinableThread("LockIsolateAndCalculateFibThread"),
344257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      isolate_(isolate),
345257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      context_(context) {
346257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
347257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
348257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void Run() {
349257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker lock(isolate_);
350257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Isolate::Scope isolate_scope(isolate_);
351257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    HandleScope handle_scope;
352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Context::Scope context_scope(context_);
353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CalcFibAndCheck();
354257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
355257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
356257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate_;
357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Persistent<v8::Context> context_;
358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass LockerUnlockerThread : public JoinableThread {
361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit LockerUnlockerThread(v8::Isolate* isolate)
363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    : JoinableThread("LockerUnlockerThread"),
364257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      isolate_(isolate) {
365257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void Run() {
368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker lock(isolate_);
369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Isolate::Scope isolate_scope(isolate_);
370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::HandleScope handle_scope;
371257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Handle<v8::Context> context = v8::Context::New();
372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Context::Scope context_scope(context);
374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CalcFibAndCheck();
375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
376257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      isolate_->Exit();
378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Unlocker unlocker(isolate_);
379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      LockIsolateAndCalculateFibSharedContextThread thread(isolate_, context);
380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      thread.Start();
381257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      thread.Join();
382257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    isolate_->Enter();
384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Context::Scope context_scope(context);
386257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CalcFibAndCheck();
387257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
388257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
389589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate_;
392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Use unlocker inside of a Locker, multiple threads.
395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(LockerUnlocker) {
3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
3973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  const int kNThreads = 50;
3983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else
399257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const int kNThreads = 100;
4003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
401257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::List<JoinableThread*> threads(kNThreads);
402257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate = v8::Isolate::New();
403257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; i < kNThreads; i++) {
404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threads.Add(new LockerUnlockerThread(isolate));
405257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
406257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StartJoinAndDeleteThreads(threads);
407257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  isolate->Dispose();
408257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
409257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
410257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass LockTwiceAndUnlockThread : public JoinableThread {
411257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
412257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit LockTwiceAndUnlockThread(v8::Isolate* isolate)
413257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    : JoinableThread("LockTwiceAndUnlockThread"),
414257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      isolate_(isolate) {
415257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
416257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
417257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void Run() {
418257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker lock(isolate_);
419257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Isolate::Scope isolate_scope(isolate_);
420257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::HandleScope handle_scope;
421257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Handle<v8::Context> context = v8::Context::New();
422257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
423257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Context::Scope context_scope(context);
424257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CalcFibAndCheck();
425257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
427257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Locker second_lock(isolate_);
428257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      {
429257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        isolate_->Exit();
430257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        v8::Unlocker unlocker(isolate_);
431257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        LockIsolateAndCalculateFibSharedContextThread thread(isolate_, context);
432257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        thread.Start();
433257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        thread.Join();
434257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
435257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
436257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    isolate_->Enter();
437257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
438257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Context::Scope context_scope(context);
439257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CalcFibAndCheck();
440257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
441257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
442589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
443257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
444257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate_;
445257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
446257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
447257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Use Unlocker inside two Lockers.
448257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(LockTwiceAndUnlock) {
4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
4503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  const int kNThreads = 50;
4513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else
452257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const int kNThreads = 100;
4533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif
454257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::List<JoinableThread*> threads(kNThreads);
455257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate = v8::Isolate::New();
456257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; i < kNThreads; i++) {
457257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threads.Add(new LockTwiceAndUnlockThread(isolate));
458257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
459257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StartJoinAndDeleteThreads(threads);
460257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  isolate->Dispose();
461257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
462257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
463257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass LockAndUnlockDifferentIsolatesThread : public JoinableThread {
464257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
465257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  LockAndUnlockDifferentIsolatesThread(v8::Isolate* isolate1,
466257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                       v8::Isolate* isolate2)
467257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    : JoinableThread("LockAndUnlockDifferentIsolatesThread"),
468257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      isolate1_(isolate1),
469257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      isolate2_(isolate2) {
470257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
471257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
472257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void Run() {
473257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Persistent<v8::Context> context1;
474257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Persistent<v8::Context> context2;
475257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker lock1(isolate1_);
476257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CHECK(v8::Locker::IsLocked(isolate1_));
477257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CHECK(!v8::Locker::IsLocked(isolate2_));
478257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
479257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Isolate::Scope isolate_scope(isolate1_);
480257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::HandleScope handle_scope;
481257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      context1 = v8::Context::New();
482257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      {
483257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        v8::Context::Scope context_scope(context1);
484257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        CalcFibAndCheck();
485257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
486257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
487257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker lock2(isolate2_);
488257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CHECK(v8::Locker::IsLocked(isolate1_));
489257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CHECK(v8::Locker::IsLocked(isolate2_));
490257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
491257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Isolate::Scope isolate_scope(isolate2_);
492257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::HandleScope handle_scope;
493257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      context2 = v8::Context::New();
494257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      {
495257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        v8::Context::Scope context_scope(context2);
496257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        CalcFibAndCheck();
497257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
498257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
499257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
500257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Unlocker unlock1(isolate1_);
501257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CHECK(!v8::Locker::IsLocked(isolate1_));
502257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CHECK(v8::Locker::IsLocked(isolate2_));
503257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Isolate::Scope isolate_scope(isolate2_);
504257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::HandleScope handle_scope;
505257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Context::Scope context_scope(context2);
506257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      LockIsolateAndCalculateFibSharedContextThread thread(isolate1_, context1);
507257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      thread.Start();
508257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CalcFibAndCheck();
509257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      thread.Join();
510257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
511257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
512589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
513257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
514257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate1_;
515257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate2_;
516257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
518257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Lock two isolates and unlock one of them.
519257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(LockAndUnlockDifferentIsolates) {
520257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate1 = v8::Isolate::New();
521257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate2 = v8::Isolate::New();
522257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  LockAndUnlockDifferentIsolatesThread thread(isolate1, isolate2);
523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread.Start();
524257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  thread.Join();
525257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  isolate2->Dispose();
526257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  isolate1->Dispose();
527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
528257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
529257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass LockUnlockLockThread : public JoinableThread {
530257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
531257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  LockUnlockLockThread(v8::Isolate* isolate, v8::Handle<v8::Context> context)
532257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    : JoinableThread("LockUnlockLockThread"),
533257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      isolate_(isolate),
534257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      context_(context) {
535257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
536257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
537257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void Run() {
538257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker lock1(isolate_);
539257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CHECK(v8::Locker::IsLocked(isolate_));
540257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CHECK(!v8::Locker::IsLocked());
541257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
542257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Isolate::Scope isolate_scope(isolate_);
543257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::HandleScope handle_scope;
544257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Context::Scope context_scope(context_);
545257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CalcFibAndCheck();
546257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
547257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
548257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Unlocker unlock1(isolate_);
549257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CHECK(!v8::Locker::IsLocked(isolate_));
550257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CHECK(!v8::Locker::IsLocked());
551257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      {
552257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        v8::Locker lock2(isolate_);
553257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        v8::Isolate::Scope isolate_scope(isolate_);
554257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        v8::HandleScope handle_scope;
555257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        CHECK(v8::Locker::IsLocked(isolate_));
556257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        CHECK(!v8::Locker::IsLocked());
557257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        v8::Context::Scope context_scope(context_);
558257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        CalcFibAndCheck();
559257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
560257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
561257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
562257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
563257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate_;
565257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Persistent<v8::Context> context_;
566257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Locker inside an Unlocker inside a Locker.
569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(LockUnlockLockMultithreaded) {
5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef V8_TARGET_ARCH_MIPS
5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const int kNThreads = 50;
5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#else
573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const int kNThreads = 100;
5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Isolate* isolate = v8::Isolate::New();
576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Persistent<v8::Context> context;
577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  {
578257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker locker_(isolate);
579257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Isolate::Scope isolate_scope(isolate);
580257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::HandleScope handle_scope;
581257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    context = v8::Context::New();
582257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::List<JoinableThread*> threads(kNThreads);
584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; i < kNThreads; i++) {
585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threads.Add(new LockUnlockLockThread(isolate, context));
586257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
587257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StartJoinAndDeleteThreads(threads);
588257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
589257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
590257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass LockUnlockLockDefaultIsolateThread : public JoinableThread {
591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit LockUnlockLockDefaultIsolateThread(v8::Handle<v8::Context> context)
593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    : JoinableThread("LockUnlockLockDefaultIsolateThread"),
594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      context_(context) {
595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
596257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
597257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  virtual void Run() {
598257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker lock1;
599257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
600257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::HandleScope handle_scope;
601257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Context::Scope context_scope(context_);
602257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CalcFibAndCheck();
603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    {
605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      v8::Unlocker unlock1;
606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      {
607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        v8::Locker lock2;
608257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        v8::HandleScope handle_scope;
609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        v8::Context::Scope context_scope(context_);
610257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        CalcFibAndCheck();
611257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
612257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
613257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
614257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
615257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
616257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  v8::Persistent<v8::Context> context_;
617257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
618257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
619257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Locker inside an Unlocker inside a Locker for default isolate.
620257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTEST(LockUnlockLockDefaultIsolateMultithreaded) {
6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef V8_TARGET_ARCH_MIPS
6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const int kNThreads = 50;
6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#else
624257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  const int kNThreads = 100;
6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
626257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Persistent<v8::Context> context;
627257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  {
628257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Locker locker_;
629257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::HandleScope handle_scope;
630257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    context = v8::Context::New();
631257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
632257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::List<JoinableThread*> threads(kNThreads);
633257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (int i = 0; i < kNThreads; i++) {
634257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    threads.Add(new LockUnlockLockDefaultIsolateThread(context));
635257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
636257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  StartJoinAndDeleteThreads(threads);
637257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
6383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
6393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
6403fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochTEST(Regress1433) {
6413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int i = 0; i < 10; i++) {
6423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    v8::Isolate* isolate = v8::Isolate::New();
6433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    {
6443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      v8::Locker lock(isolate);
6453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      v8::Isolate::Scope isolate_scope(isolate);
6463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      v8::HandleScope handle_scope;
6473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      v8::Persistent<Context> context = v8::Context::New();
6483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      v8::Context::Scope context_scope(context);
6493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      v8::Handle<String> source = v8::String::New("1+1");
6503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      v8::Handle<Script> script = v8::Script::Compile(source);
6513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      v8::Handle<Value> result = script->Run();
6523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      v8::String::AsciiValue ascii(result);
6533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      context.Dispose();
6543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
6553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    isolate->Dispose();
6563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
6573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const char* kSimpleExtensionSource =
6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  "(function Foo() {"
6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  "  return 4;"
6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  "})() ";
6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass IsolateGenesisThread : public JoinableThread {
6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IsolateGenesisThread(int count, const char* extension_names[])
6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : JoinableThread("IsolateGenesisThread"),
6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      count_(count),
6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      extension_names_(extension_names)
6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  {}
6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  virtual void Run() {
6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    v8::Isolate* isolate = v8::Isolate::New();
6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    {
6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      v8::Isolate::Scope isolate_scope(isolate);
6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      CHECK(!i::Isolate::Current()->has_installed_extensions());
6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      v8::ExtensionConfiguration extensions(count_, extension_names_);
6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      v8::Persistent<v8::Context> context = v8::Context::New(&extensions);
6803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      CHECK(i::Isolate::Current()->has_installed_extensions());
6813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      context.Dispose();
6823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
6833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    isolate->Dispose();
6843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
6863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int count_;
6873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const char** extension_names_;
6883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test installing extensions in separate isolates concurrently.
6913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// http://code.google.com/p/v8/issues/detail?id=1821
6923ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(ExtensionsRegistration) {
6933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
6943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const int kNThreads = 10;
6953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#else
6963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const int kNThreads = 40;
6973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
6983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::RegisterExtension(new v8::Extension("test0",
6993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          kSimpleExtensionSource));
7003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::RegisterExtension(new v8::Extension("test1",
7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          kSimpleExtensionSource));
7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::RegisterExtension(new v8::Extension("test2",
7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          kSimpleExtensionSource));
7043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::RegisterExtension(new v8::Extension("test3",
7053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          kSimpleExtensionSource));
7063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::RegisterExtension(new v8::Extension("test4",
7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          kSimpleExtensionSource));
7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::RegisterExtension(new v8::Extension("test5",
7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          kSimpleExtensionSource));
7103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::RegisterExtension(new v8::Extension("test6",
7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          kSimpleExtensionSource));
7123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v8::RegisterExtension(new v8::Extension("test7",
7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          kSimpleExtensionSource));
7143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const char* extension_names[] = { "test0", "test1",
7153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    "test2", "test3", "test4",
7163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    "test5", "test6", "test7" };
7173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::List<JoinableThread*> threads(kNThreads);
7183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < kNThreads; i++) {
7193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    threads.Add(new IsolateGenesisThread(8, extension_names));
7203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StartJoinAndDeleteThreads(threads);
7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
723