Revision: 7187
Author: [email protected]
Date: Tue Mar 15 18:30:44 2011
Log: [Isolates] Enter default isolate in initializing API.
Review URL: http://codereview.chromium.org/6672029
http://code.google.com/p/v8/source/detail?r=7187

Modified:
 /branches/experimental/isolates/src/api.cc
 /branches/experimental/isolates/test/cctest/test-api.cc

=======================================
--- /branches/experimental/isolates/src/api.cc  Fri Mar 11 19:15:52 2011
+++ /branches/experimental/isolates/src/api.cc  Tue Mar 15 18:30:44 2011
@@ -201,12 +201,6 @@
   // If the callback returns, we stop execution.
   UNREACHABLE();
 }
-
-
-void V8::SetFatalErrorHandler(FatalErrorCallback that) {
-  i::Isolate* isolate = i::Isolate::Current();
-  isolate->set_exception_behavior(that);
-}


 bool Utils::ReportApiFailure(const char* location, const char* message) {
@@ -292,6 +286,30 @@
   i::Isolate* isolate = i::Isolate::UncheckedCurrent();
   return EnsureInitializedForIsolate(isolate, location);
 }
+
+// Some initializing API functions are called early and may be
+// called on a thread different from static initializer thread.
+// If Isolate API is used, Isolate::Enter() will initialize TLS so
+// Isolate::Current() works. If it's a legacy case, then the thread
+// may not have TLS initialized yet. However, in initializing APIs it
+// may be too early to call EnsureInitialized() - some pre-init
+// parameters still have to be configured.
+static inline i::Isolate* EnterIsolateIfNeeded() {
+  i::Isolate* isolate = i::Isolate::UncheckedCurrent();
+  if (isolate != NULL)
+    return isolate;
+
+  i::Isolate::EnterDefaultIsolate();
+  isolate = i::Isolate::Current();
+  return isolate;
+}
+
+
+void V8::SetFatalErrorHandler(FatalErrorCallback that) {
+  i::Isolate* isolate = EnterIsolateIfNeeded();
+  isolate->set_exception_behavior(that);
+}
+

 #ifdef DEBUG
 void ImplementationUtilities::ZapHandleRange(i::Object** begin,
@@ -414,12 +432,14 @@


 bool SetResourceConstraints(ResourceConstraints* constraints) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = EnterIsolateIfNeeded();

   int young_space_size = constraints->max_young_space_size();
   int old_gen_size = constraints->max_old_space_size();
   int max_executable_size = constraints->max_executable_size();
if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
+    // After initialization it's too late to change Heap constraints.
+    ASSERT(!isolate->IsInitialized());
     bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
                                                  old_gen_size,
                                                  max_executable_size);
@@ -4032,7 +4052,7 @@


 void V8::IgnoreOutOfMemoryException() {
- i::Isolate::Current()->handle_scope_implementer()->set_ignore_out_of_memory( + EnterIsolateIfNeeded()->handle_scope_implementer()->set_ignore_out_of_memory(
       true);
 }

=======================================
--- /branches/experimental/isolates/test/cctest/test-api.cc Thu Mar 10 10:19:06 2011 +++ /branches/experimental/isolates/test/cctest/test-api.cc Tue Mar 15 18:30:44 2011
@@ -2081,8 +2081,6 @@
 TEST(HugeConsStringOutOfMemory) {
// It's not possible to read a snapshot into a heap with different dimensions.
   if (i::Snapshot::IsEnabled()) return;
-  v8::HandleScope scope;
-  LocalContext context;
   // Set heap limits.
   static const int K = 1024;
   v8::ResourceConstraints constraints;
@@ -2093,6 +2091,9 @@
   // Execute a script that causes out of memory.
   v8::V8::IgnoreOutOfMemoryException();

+  v8::HandleScope scope;
+  LocalContext context;
+
   // Build huge string. This should fail with out of memory exception.
   Local<Value> result = CompileRun(
"var str = Array.prototype.join.call({length: 513}, \"A\").toUpperCase();"
@@ -12885,6 +12886,66 @@
   isolate1->Dispose();
   isolate2->Dispose();
 }
+
+
+class InitDefaultIsolateThread : public v8::internal::Thread {
+ public:
+  enum TestCase { IgnoreOOM, SetResourceConstraints, SetFatalHandler };
+
+  explicit InitDefaultIsolateThread(TestCase testCase)
+    : Thread(NULL),
+      testCase_(testCase),
+      result_(false) { }
+
+  void Run() {
+    switch (testCase_) {
+    case IgnoreOOM:
+      v8::V8::IgnoreOutOfMemoryException();
+      break;
+
+    case SetResourceConstraints: {
+      static const int K = 1024;
+      v8::ResourceConstraints constraints;
+      constraints.set_max_young_space_size(256 * K);
+      constraints.set_max_old_space_size(4 * K * K);
+      v8::SetResourceConstraints(&constraints);
+      break;
+    }
+
+    case SetFatalHandler:
+      v8::V8::SetFatalErrorHandler(NULL);
+      break;
+
+    }
+    result_ = true;
+  }
+
+  bool result() { return result_; }
+
+ private:
+  TestCase testCase_;
+  bool result_;
+};
+
+
+static void InitializeTestHelper(InitDefaultIsolateThread::TestCase testCase) {
+  InitDefaultIsolateThread thread(testCase);
+  thread.Start();
+  thread.Join();
+  CHECK_EQ(thread.result(), true);
+}
+
+TEST(InitializeDefaultIsolateOnSecondaryThread1) {
+  InitializeTestHelper(InitDefaultIsolateThread::IgnoreOOM);
+}
+
+TEST(InitializeDefaultIsolateOnSecondaryThread2) {
+  InitializeTestHelper(InitDefaultIsolateThread::SetResourceConstraints);
+}
+
+TEST(InitializeDefaultIsolateOnSecondaryThread3) {
+  InitializeTestHelper(InitDefaultIsolateThread::SetFatalHandler);
+}


 TEST(StringCheckMultipleContexts) {

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to