Files
sdk/runtime/bin/run_vm_tests.cc
T
Vyacheslav Egorov a5e1f89583 VM: Fix an app-jit related shutdown race.
IsolateData contains AppSnapshot which might own some HeapPage-s, so we can't
destroy IsolateData in the Dart_IsolateShutdownCallback, because some thread
running in the isolate (e.g. background compiler) might still touch
thoses pages or objects they host.

We need to delay destruction of AppSnapshot until after the isolate shutdown.

Current API does not allow that, so we introduce a new isolate lifecycle
callback - Dart_IsolateCleanupCallback, which is invoked at the end of the
isolote lifecycle when things like background compiler have been stopped
and no Dart code is supposed to run.

BUG=
R=rmacnak@google.com

Review-Url: https://codereview.chromium.org/2720723005 .
2017-02-28 21:10:04 +01:00

156 lines
4.3 KiB
C++

// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include <stdio.h>
#include "bin/dartutils.h"
#include "bin/file.h"
#include "bin/platform.h"
#include "platform/assert.h"
#include "vm/benchmark_test.h"
#include "vm/dart.h"
#include "vm/unit_test.h"
// TODO(iposva, asiva): This is a placeholder for the real unittest framework.
namespace dart {
// Defined in vm/os_thread_win.cc
extern bool private_flag_windows_run_tls_destructors;
// vm_snapshot_data_buffer points to a snapshot for the vm isolate if we
// link in a snapshot otherwise it is initialized to NULL.
extern const uint8_t* bin::vm_snapshot_data;
extern const uint8_t* bin::vm_snapshot_instructions;
// Only run tests that match the filter string. The default does not match any
// tests.
static const char* const kNone = "No Test or Benchmarks";
static const char* const kList = "List all Tests and Benchmarks";
static const char* const kAllBenchmarks = "All Benchmarks";
static const char* run_filter = kNone;
static int run_matches = 0;
void TestCase::Run() {
OS::Print("Running test: %s\n", name());
(*run_)();
OS::Print("Done: %s\n", name());
}
void RawTestCase::Run() {
OS::Print("Running test: %s\n", name());
(*run_)();
OS::Print("Done: %s\n", name());
}
void TestCaseBase::RunTest() {
if (strcmp(run_filter, this->name()) == 0) {
this->Run();
run_matches++;
} else if (run_filter == kList) {
OS::Print("%s\n", this->name());
run_matches++;
}
}
void Benchmark::RunBenchmark() {
if ((run_filter == kAllBenchmarks) ||
(strcmp(run_filter, this->name()) == 0)) {
this->Run();
OS::Print("%s(%s): %" Pd64 "\n", this->name(), this->score_kind(),
this->score());
run_matches++;
} else if (run_filter == kList) {
OS::Print("%s\n", this->name());
run_matches++;
}
}
static void PrintUsage() {
OS::PrintErr(
"run_vm_tests [--list | --benchmarks | "
"<test name> | <benchmark name>]\n");
OS::PrintErr("run_vm_tests [vm-flags ...] <test name>\n");
OS::PrintErr("run_vm_tests [vm-flags ...] <benchmark name>\n");
}
static int Main(int argc, const char** argv) {
// Flags being passed to the Dart VM.
int dart_argc = 0;
const char** dart_argv = NULL;
// Perform platform specific initialization.
if (!dart::bin::Platform::Initialize()) {
OS::PrintErr("Initialization failed\n");
}
if (argc < 2) {
// Bad parameter count.
PrintUsage();
return 1;
} else if (argc == 2) {
if (strcmp(argv[1], "--list") == 0) {
run_filter = kList;
// List all tests and benchmarks and exit without initializing the VM.
TestCaseBase::RunAll();
Benchmark::RunAll(argv[0]);
TestCaseBase::RunAllRaw();
fflush(stdout);
return 0;
} else if (strcmp(argv[1], "--benchmarks") == 0) {
run_filter = kAllBenchmarks;
} else {
run_filter = argv[1];
}
} else {
// Last argument is the test name, the rest are vm flags.
run_filter = argv[argc - 1];
// Remove the first value (executable) from the arguments and
// exclude the last argument which is the test name.
dart_argc = argc - 2;
dart_argv = &argv[1];
}
bool set_vm_flags_success =
Flags::ProcessCommandLineFlags(dart_argc, dart_argv);
ASSERT(set_vm_flags_success);
const char* err_msg = Dart::InitOnce(
dart::bin::vm_snapshot_data, dart::bin::vm_snapshot_instructions, NULL,
NULL, NULL, NULL, dart::bin::DartUtils::OpenFile,
dart::bin::DartUtils::ReadFile, dart::bin::DartUtils::WriteFile,
dart::bin::DartUtils::CloseFile, NULL, NULL);
ASSERT(err_msg == NULL);
// Apply the filter to all registered tests.
TestCaseBase::RunAll();
// Apply the filter to all registered benchmarks.
Benchmark::RunAll(argv[0]);
err_msg = Dart::Cleanup();
ASSERT(err_msg == NULL);
TestCaseBase::RunAllRaw();
// Print a warning message if no tests or benchmarks were matched.
if (run_matches == 0) {
OS::PrintErr("No tests matched: %s\n", run_filter);
return 1;
}
if (DynamicAssertionHelper::failed()) {
return 255;
}
return 0;
}
} // namespace dart
int main(int argc, const char** argv) {
dart::bin::Platform::Exit(dart::Main(argc, argv));
}