OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 // Defined when linking against shared lib on Windows. | 6 // Defined when linking against shared lib on Windows. |
7 #if defined(USING_V8_SHARED) && !defined(V8_SHARED) | 7 #if defined(USING_V8_SHARED) && !defined(V8_SHARED) |
8 #define V8_SHARED | 8 #define V8_SHARED |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 return result; | 289 return result; |
290 } | 290 } |
291 | 291 |
292 | 292 |
293 // Executes a string within the current v8 context. | 293 // Executes a string within the current v8 context. |
294 bool Shell::ExecuteString(Isolate* isolate, Local<String> source, | 294 bool Shell::ExecuteString(Isolate* isolate, Local<String> source, |
295 Local<Value> name, bool print_result, | 295 Local<Value> name, bool print_result, |
296 bool report_exceptions, SourceType source_type) { | 296 bool report_exceptions, SourceType source_type) { |
297 HandleScope handle_scope(isolate); | 297 HandleScope handle_scope(isolate); |
298 TryCatch try_catch(isolate); | 298 TryCatch try_catch(isolate); |
299 options.script_executed = true; | |
300 | 299 |
301 MaybeLocal<Value> maybe_result; | 300 MaybeLocal<Value> maybe_result; |
302 { | 301 { |
303 PerIsolateData* data = PerIsolateData::Get(isolate); | 302 PerIsolateData* data = PerIsolateData::Get(isolate); |
304 Local<Context> realm = | 303 Local<Context> realm = |
305 Local<Context>::New(isolate, data->realms_[data->realm_current_]); | 304 Local<Context>::New(isolate, data->realms_[data->realm_current_]); |
306 Context::Scope context_scope(realm); | 305 Context::Scope context_scope(realm); |
307 Local<Script> script; | 306 Local<Script> script; |
308 if (!Shell::CompileString(isolate, source, name, options.compile_options, | 307 if (!Shell::CompileString(isolate, source, name, options.compile_options, |
309 source_type).ToLocal(&script)) { | 308 source_type).ToLocal(&script)) { |
(...skipping 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 // The stack size should be at least StackGuard::kLimitSize + some | 1482 // The stack size should be at least StackGuard::kLimitSize + some |
1484 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. | 1483 // OS-specific padding for thread startup code. 2Mbytes seems to be enough. |
1485 return base::Thread::Options("IsolateThread", 2 * MB); | 1484 return base::Thread::Options("IsolateThread", 2 * MB); |
1486 } | 1485 } |
1487 | 1486 |
1488 | 1487 |
1489 void SourceGroup::ExecuteInThread() { | 1488 void SourceGroup::ExecuteInThread() { |
1490 Isolate::CreateParams create_params; | 1489 Isolate::CreateParams create_params; |
1491 create_params.array_buffer_allocator = Shell::array_buffer_allocator; | 1490 create_params.array_buffer_allocator = Shell::array_buffer_allocator; |
1492 Isolate* isolate = Isolate::New(create_params); | 1491 Isolate* isolate = Isolate::New(create_params); |
1493 do { | 1492 for (int i = 0; i < Shell::options.stress_runs; ++i) { |
1494 next_semaphore_.Wait(); | 1493 next_semaphore_.Wait(); |
1495 { | 1494 { |
1496 Isolate::Scope iscope(isolate); | 1495 Isolate::Scope iscope(isolate); |
1497 { | 1496 { |
1498 HandleScope scope(isolate); | 1497 HandleScope scope(isolate); |
1499 PerIsolateData data(isolate); | 1498 PerIsolateData data(isolate); |
1500 Local<Context> context = Shell::CreateEvaluationContext(isolate); | 1499 Local<Context> context = Shell::CreateEvaluationContext(isolate); |
1501 { | 1500 { |
1502 Context::Scope cscope(context); | 1501 Context::Scope cscope(context); |
1503 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 1502 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
1504 Execute(isolate); | 1503 Execute(isolate); |
1505 } | 1504 } |
1506 } | 1505 } |
1507 Shell::CollectGarbage(isolate); | 1506 Shell::CollectGarbage(isolate); |
1508 } | 1507 } |
1509 done_semaphore_.Signal(); | 1508 done_semaphore_.Signal(); |
1510 } while (!Shell::options.last_run); | 1509 } |
1511 | 1510 |
1512 isolate->Dispose(); | 1511 isolate->Dispose(); |
1513 } | 1512 } |
1514 | 1513 |
1515 | 1514 |
1516 void SourceGroup::StartExecuteInThread() { | 1515 void SourceGroup::StartExecuteInThread() { |
1517 if (thread_ == NULL) { | 1516 if (thread_ == NULL) { |
1518 thread_ = new IsolateThread(this); | 1517 thread_ = new IsolateThread(this); |
1519 thread_->Start(); | 1518 thread_->Start(); |
1520 } | 1519 } |
1521 next_semaphore_.Signal(); | 1520 next_semaphore_.Signal(); |
1522 } | 1521 } |
1523 | 1522 |
1524 | 1523 |
1525 void SourceGroup::WaitForThread() { | 1524 void SourceGroup::WaitForThread() { |
1526 if (thread_ == NULL) return; | 1525 if (thread_ == NULL) return; |
1527 if (Shell::options.last_run) { | 1526 done_semaphore_.Wait(); |
1528 thread_->Join(); | |
1529 } else { | |
1530 done_semaphore_.Wait(); | |
1531 } | |
1532 } | 1527 } |
1533 | 1528 |
1534 | 1529 |
| 1530 void SourceGroup::JoinThread() { |
| 1531 if (thread_ == NULL) return; |
| 1532 thread_->Join(); |
| 1533 } |
| 1534 |
| 1535 |
1535 SerializationData::~SerializationData() { | 1536 SerializationData::~SerializationData() { |
1536 // Any ArrayBuffer::Contents are owned by this SerializationData object if | 1537 // Any ArrayBuffer::Contents are owned by this SerializationData object if |
1537 // ownership hasn't been transferred out via ReadArrayBufferContents. | 1538 // ownership hasn't been transferred out via ReadArrayBufferContents. |
1538 // SharedArrayBuffer::Contents may be used by multiple threads, so must be | 1539 // SharedArrayBuffer::Contents may be used by multiple threads, so must be |
1539 // cleaned up by the main thread in Shell::CleanupWorkers(). | 1540 // cleaned up by the main thread in Shell::CleanupWorkers(). |
1540 for (int i = 0; i < array_buffer_contents_.length(); ++i) { | 1541 for (int i = 0; i < array_buffer_contents_.length(); ++i) { |
1541 ArrayBuffer::Contents& contents = array_buffer_contents_[i]; | 1542 ArrayBuffer::Contents& contents = array_buffer_contents_[i]; |
1542 if (contents.Data()) { | 1543 if (contents.Data()) { |
1543 Shell::array_buffer_allocator->Free(contents.Data(), | 1544 Shell::array_buffer_allocator->Free(contents.Data(), |
1544 contents.ByteLength()); | 1545 contents.ByteLength()); |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1927 const char* str = argv[i]; | 1928 const char* str = argv[i]; |
1928 if (strcmp(str, "--isolate") == 0) { | 1929 if (strcmp(str, "--isolate") == 0) { |
1929 current->End(i); | 1930 current->End(i); |
1930 current++; | 1931 current++; |
1931 current->Begin(argv, i + 1); | 1932 current->Begin(argv, i + 1); |
1932 } else if (strcmp(str, "--module") == 0) { | 1933 } else if (strcmp(str, "--module") == 0) { |
1933 // Pass on to SourceGroup, which understands this option. | 1934 // Pass on to SourceGroup, which understands this option. |
1934 enable_harmony_modules = true; | 1935 enable_harmony_modules = true; |
1935 } else if (strncmp(argv[i], "--", 2) == 0) { | 1936 } else if (strncmp(argv[i], "--", 2) == 0) { |
1936 printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]); | 1937 printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]); |
| 1938 } else if (strcmp(str, "-e") == 0 && i + 1 < argc) { |
| 1939 options.script_executed = true; |
| 1940 } else if (strncmp(str, "-", 1) != 0) { |
| 1941 // Not a flag, so it must be a script to execute. |
| 1942 options.script_executed = true; |
1937 } | 1943 } |
1938 } | 1944 } |
1939 current->End(argc); | 1945 current->End(argc); |
1940 | 1946 |
1941 if (!logfile_per_isolate && options.num_isolates) { | 1947 if (!logfile_per_isolate && options.num_isolates) { |
1942 SetFlagsFromString("--nologfile_per_isolate"); | 1948 SetFlagsFromString("--nologfile_per_isolate"); |
1943 } | 1949 } |
1944 | 1950 |
1945 if (enable_harmony_modules) { | 1951 if (enable_harmony_modules) { |
1946 SetFlagsFromString("--harmony-modules"); | 1952 SetFlagsFromString("--harmony-modules"); |
1947 } | 1953 } |
1948 | 1954 |
1949 return true; | 1955 return true; |
1950 } | 1956 } |
1951 | 1957 |
1952 | 1958 |
1953 int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) { | 1959 int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) { |
1954 #ifndef V8_SHARED | 1960 #ifndef V8_SHARED |
1955 for (int i = 1; i < options.num_isolates; ++i) { | 1961 for (int i = 1; i < options.num_isolates; ++i) { |
1956 options.isolate_sources[i].StartExecuteInThread(); | 1962 options.isolate_sources[i].StartExecuteInThread(); |
1957 } | 1963 } |
1958 #endif // !V8_SHARED | 1964 #endif // !V8_SHARED |
1959 { | 1965 { |
1960 HandleScope scope(isolate); | 1966 HandleScope scope(isolate); |
1961 Local<Context> context = CreateEvaluationContext(isolate); | 1967 Local<Context> context = CreateEvaluationContext(isolate); |
1962 if (options.last_run && options.use_interactive_shell()) { | 1968 if (last_run && options.use_interactive_shell()) { |
1963 // Keep using the same context in the interactive shell. | 1969 // Keep using the same context in the interactive shell. |
1964 evaluation_context_.Reset(isolate, context); | 1970 evaluation_context_.Reset(isolate, context); |
1965 } | 1971 } |
1966 { | 1972 { |
1967 Context::Scope cscope(context); | 1973 Context::Scope cscope(context); |
1968 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); | 1974 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); |
1969 options.isolate_sources[0].Execute(isolate); | 1975 options.isolate_sources[0].Execute(isolate); |
1970 } | 1976 } |
1971 } | 1977 } |
1972 CollectGarbage(isolate); | 1978 CollectGarbage(isolate); |
1973 #ifndef V8_SHARED | 1979 #ifndef V8_SHARED |
1974 for (int i = 1; i < options.num_isolates; ++i) { | 1980 for (int i = 1; i < options.num_isolates; ++i) { |
1975 options.isolate_sources[i].WaitForThread(); | 1981 if (last_run) { |
| 1982 options.isolate_sources[i].JoinThread(); |
| 1983 } else { |
| 1984 options.isolate_sources[i].WaitForThread(); |
| 1985 } |
1976 } | 1986 } |
1977 CleanupWorkers(); | 1987 CleanupWorkers(); |
1978 #endif // !V8_SHARED | 1988 #endif // !V8_SHARED |
1979 return 0; | 1989 return 0; |
1980 } | 1990 } |
1981 | 1991 |
1982 | 1992 |
1983 void Shell::CollectGarbage(Isolate* isolate) { | 1993 void Shell::CollectGarbage(Isolate* isolate) { |
1984 if (options.send_idle_notification) { | 1994 if (options.send_idle_notification) { |
1985 const double kLongIdlePauseInSeconds = 1.0; | 1995 const double kLongIdlePauseInSeconds = 1.0; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2091 if (!FindInObjectList(sab, to_transfer)) { | 2101 if (!FindInObjectList(sab, to_transfer)) { |
2092 Throw(isolate, "SharedArrayBuffer must be transferred"); | 2102 Throw(isolate, "SharedArrayBuffer must be transferred"); |
2093 return false; | 2103 return false; |
2094 } | 2104 } |
2095 | 2105 |
2096 SharedArrayBuffer::Contents contents; | 2106 SharedArrayBuffer::Contents contents; |
2097 if (sab->IsExternal()) { | 2107 if (sab->IsExternal()) { |
2098 contents = sab->GetContents(); | 2108 contents = sab->GetContents(); |
2099 } else { | 2109 } else { |
2100 contents = sab->Externalize(); | 2110 contents = sab->Externalize(); |
| 2111 base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer()); |
2101 externalized_shared_contents_.Add(contents); | 2112 externalized_shared_contents_.Add(contents); |
2102 } | 2113 } |
2103 out_data->WriteSharedArrayBufferContents(contents); | 2114 out_data->WriteSharedArrayBufferContents(contents); |
2104 } else if (value->IsObject()) { | 2115 } else if (value->IsObject()) { |
2105 Local<Object> object = Local<Object>::Cast(value); | 2116 Local<Object> object = Local<Object>::Cast(value); |
2106 if (FindInObjectList(object, *seen_objects)) { | 2117 if (FindInObjectList(object, *seen_objects)) { |
2107 Throw(isolate, "Duplicated objects not supported"); | 2118 Throw(isolate, "Duplicated objects not supported"); |
2108 return false; | 2119 return false; |
2109 } | 2120 } |
2110 seen_objects->Add(object); | 2121 seen_objects->Add(object); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2246 workers_.Clear(); | 2257 workers_.Clear(); |
2247 } | 2258 } |
2248 | 2259 |
2249 for (int i = 0; i < workers_copy.length(); ++i) { | 2260 for (int i = 0; i < workers_copy.length(); ++i) { |
2250 Worker* worker = workers_copy[i]; | 2261 Worker* worker = workers_copy[i]; |
2251 worker->WaitForThread(); | 2262 worker->WaitForThread(); |
2252 delete worker; | 2263 delete worker; |
2253 } | 2264 } |
2254 | 2265 |
2255 // Now that all workers are terminated, we can re-enable Worker creation. | 2266 // Now that all workers are terminated, we can re-enable Worker creation. |
2256 { | 2267 base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer()); |
2257 base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer()); | 2268 allow_new_workers_ = true; |
2258 allow_new_workers_ = true; | |
2259 } | |
2260 | 2269 |
2261 for (int i = 0; i < externalized_shared_contents_.length(); ++i) { | 2270 for (int i = 0; i < externalized_shared_contents_.length(); ++i) { |
2262 const SharedArrayBuffer::Contents& contents = | 2271 const SharedArrayBuffer::Contents& contents = |
2263 externalized_shared_contents_[i]; | 2272 externalized_shared_contents_[i]; |
2264 Shell::array_buffer_allocator->Free(contents.Data(), contents.ByteLength()); | 2273 Shell::array_buffer_allocator->Free(contents.Data(), contents.ByteLength()); |
2265 } | 2274 } |
2266 externalized_shared_contents_.Clear(); | 2275 externalized_shared_contents_.Clear(); |
2267 } | 2276 } |
2268 | 2277 |
2269 | 2278 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2391 if (options.dump_heap_constants) { | 2400 if (options.dump_heap_constants) { |
2392 DumpHeapConstants(reinterpret_cast<i::Isolate*>(isolate)); | 2401 DumpHeapConstants(reinterpret_cast<i::Isolate*>(isolate)); |
2393 return 0; | 2402 return 0; |
2394 } | 2403 } |
2395 #endif | 2404 #endif |
2396 | 2405 |
2397 if (options.stress_opt || options.stress_deopt) { | 2406 if (options.stress_opt || options.stress_deopt) { |
2398 Testing::SetStressRunType(options.stress_opt | 2407 Testing::SetStressRunType(options.stress_opt |
2399 ? Testing::kStressTypeOpt | 2408 ? Testing::kStressTypeOpt |
2400 : Testing::kStressTypeDeopt); | 2409 : Testing::kStressTypeDeopt); |
2401 int stress_runs = Testing::GetStressRuns(); | 2410 options.stress_runs = Testing::GetStressRuns(); |
2402 for (int i = 0; i < stress_runs && result == 0; i++) { | 2411 for (int i = 0; i < options.stress_runs && result == 0; i++) { |
2403 printf("============ Stress %d/%d ============\n", i + 1, stress_runs); | 2412 printf("============ Stress %d/%d ============\n", i + 1, |
| 2413 options.stress_runs); |
2404 Testing::PrepareStressRun(i); | 2414 Testing::PrepareStressRun(i); |
2405 options.last_run = (i == stress_runs - 1); | 2415 bool last_run = i == options.stress_runs - 1; |
2406 result = RunMain(isolate, argc, argv); | 2416 result = RunMain(isolate, argc, argv, last_run); |
2407 } | 2417 } |
2408 printf("======== Full Deoptimization =======\n"); | 2418 printf("======== Full Deoptimization =======\n"); |
2409 Testing::DeoptimizeAll(); | 2419 Testing::DeoptimizeAll(); |
2410 #if !defined(V8_SHARED) | 2420 #if !defined(V8_SHARED) |
2411 } else if (i::FLAG_stress_runs > 0) { | 2421 } else if (i::FLAG_stress_runs > 0) { |
2412 int stress_runs = i::FLAG_stress_runs; | 2422 options.stress_runs = i::FLAG_stress_runs; |
2413 for (int i = 0; i < stress_runs && result == 0; i++) { | 2423 for (int i = 0; i < options.stress_runs && result == 0; i++) { |
2414 printf("============ Run %d/%d ============\n", i + 1, stress_runs); | 2424 printf("============ Run %d/%d ============\n", i + 1, |
2415 options.last_run = (i == stress_runs - 1); | 2425 options.stress_runs); |
2416 result = RunMain(isolate, argc, argv); | 2426 bool last_run = i == options.stress_runs - 1; |
| 2427 result = RunMain(isolate, argc, argv, last_run); |
2417 } | 2428 } |
2418 #endif | 2429 #endif |
2419 } else { | 2430 } else { |
2420 result = RunMain(isolate, argc, argv); | 2431 bool last_run = true; |
| 2432 result = RunMain(isolate, argc, argv, last_run); |
2421 } | 2433 } |
2422 | 2434 |
2423 // Run interactive shell if explicitly requested or if no script has been | 2435 // Run interactive shell if explicitly requested or if no script has been |
2424 // executed, but never on --test | 2436 // executed, but never on --test |
2425 if (options.use_interactive_shell()) { | 2437 if (options.use_interactive_shell()) { |
2426 #ifndef V8_SHARED | 2438 #ifndef V8_SHARED |
2427 InstallUtilityScript(isolate); | 2439 InstallUtilityScript(isolate); |
2428 #endif // !V8_SHARED | 2440 #endif // !V8_SHARED |
2429 RunShell(isolate); | 2441 RunShell(isolate); |
2430 } | 2442 } |
(...skipping 23 matching lines...) Expand all Loading... |
2454 } | 2466 } |
2455 | 2467 |
2456 } // namespace v8 | 2468 } // namespace v8 |
2457 | 2469 |
2458 | 2470 |
2459 #ifndef GOOGLE3 | 2471 #ifndef GOOGLE3 |
2460 int main(int argc, char* argv[]) { | 2472 int main(int argc, char* argv[]) { |
2461 return v8::Shell::Main(argc, argv); | 2473 return v8::Shell::Main(argc, argv); |
2462 } | 2474 } |
2463 #endif | 2475 #endif |
OLD | NEW |