| 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 |