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