Skip to content

Commit e72c1fb

Browse files
committed
Implement safepointing of threads :
- uses thread execution status transition to track when a thread is in a safepoint or needs to block for a safepoint - introduces a monitor per Thread object - uses a per thread safepoint handshake between the thread requesting a safepoint and the requested thread. The ThreadRegistry class now contains only the thread list for an isolate and the functionality of scheduling a thread onto an Isolate and unscheduling it from teh isolate. We could fold this functionality into the Isolate class in a different CL. R=rmacnak@google.com, zra@google.com Review URL: https://codereview.chromium.org/1541073002 .
1 parent 2232a52 commit e72c1fb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1675
-861
lines changed

runtime/lib/isolate.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ static const char* CanonicalizeUri(Thread* thread,
298298
Isolate* isolate = thread->isolate();
299299
Dart_LibraryTagHandler handler = isolate->library_tag_handler();
300300
if (handler != NULL) {
301+
TransitionVMToNative transition(thread);
301302
Dart_EnterScope();
302303
Dart_Handle handle = handler(Dart_kCanonicalizeUrl,
303304
Api::NewHandle(thread, library.raw()),

runtime/lib/vmservice.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ static void FilenameFinalizer(void* peer) {
353353

354354
DEFINE_NATIVE_ENTRY(VMService_DecodeAssets, 1) {
355355
GET_NON_NULL_NATIVE_ARGUMENT(TypedData, data, arguments->NativeArgAt(0));
356+
TransitionVMToNative transition(thread);
356357
Api::Scope scope(thread);
357358

358359
Dart_Handle data_handle = Api::NewHandle(thread, data.raw());

runtime/vm/benchmark_test.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ void Benchmark::RunAll(const char* executable) {
3939
BENCHMARK(CorelibCompileAll) {
4040
bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
4141
bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
42+
TransitionNativeToVM transition(thread);
4243
Timer timer(true, "Compile all of Core lib benchmark");
4344
timer.Start();
4445
const Error& error = Error::Handle(Library::CompileAll());
@@ -55,6 +56,7 @@ BENCHMARK(CorelibCompileAll) {
5556
BENCHMARK(CorelibCompilerStats) {
5657
bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
5758
bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
59+
TransitionNativeToVM transition(thread);
5860
CompilerStats* stats = thread->isolate()->compiler_stats();
5961
ASSERT(stats != NULL);
6062
stats->EnableBenchmark();
@@ -78,15 +80,15 @@ BENCHMARK(CorelibIsolateStartup) {
7880
const int kNumIterations = 1000;
7981
Timer timer(true, "CorelibIsolateStartup");
8082
Isolate* isolate = thread->isolate();
81-
Thread::ExitIsolate();
83+
Dart_ExitIsolate();
8284
for (int i = 0; i < kNumIterations; i++) {
8385
timer.Start();
8486
TestCase::CreateTestIsolate();
8587
timer.Stop();
8688
Dart_ShutdownIsolate();
8789
}
8890
benchmark->set_score(timer.TotalElapsedTime() / kNumIterations);
89-
Thread::EnterIsolate(isolate);
91+
Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(isolate));
9092
}
9193

9294

@@ -142,7 +144,7 @@ static Dart_NativeFunction bm_uda_lookup(Dart_Handle name,
142144
int argument_count,
143145
bool* auto_setup_scope) {
144146
ASSERT(auto_setup_scope != NULL);
145-
*auto_setup_scope = false;
147+
*auto_setup_scope = true;
146148
const char* cstr = NULL;
147149
Dart_Handle result = Dart_StringToCString(name, &cstr);
148150
EXPECT_VALID(result);
@@ -693,6 +695,7 @@ BENCHMARK(SerializeSmi) {
693695

694696

695697
BENCHMARK(SimpleMessage) {
698+
TransitionNativeToVM transition(thread);
696699
const Array& array_object = Array::Handle(Array::New(2));
697700
array_object.SetAt(0, Integer::Handle(Smi::New(42)));
698701
array_object.SetAt(1, Object::Handle());

runtime/vm/bootstrap.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ static Dart_Handle BootstrapLibraryTagHandler(Dart_LibraryTag tag,
209209
Dart_Handle uri) {
210210
Thread* thread = Thread::Current();
211211
Zone* zone = thread->zone();
212+
// This handler calls into the VM directly and does not use the Dart
213+
// API so we transition back to VM.
214+
TransitionNativeToVM transition(thread);
212215
if (!Dart_IsLibrary(library)) {
213216
return Api::NewError("not a library");
214217
}

runtime/vm/code_descriptors_test.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,10 @@ static void NativeFunc(Dart_NativeArguments args) {
178178
EXPECT_EQ(10, value);
179179
EXPECT_VALID(Dart_IntegerToInt64(k, &value));
180180
EXPECT_EQ(20, value);
181-
Isolate::Current()->heap()->CollectAllGarbage();
181+
{
182+
TransitionNativeToVM transition(Thread::Current());
183+
Isolate::Current()->heap()->CollectAllGarbage();
184+
}
182185
}
183186

184187

@@ -211,6 +214,8 @@ TEST_CASE(StackmapGC) {
211214
"}\n";
212215
// First setup the script and compile the script.
213216
TestCase::LoadTestScript(kScriptChars, native_resolver);
217+
TransitionNativeToVM transition(thread);
218+
214219
EXPECT(ClassFinalizer::ProcessPendingClasses());
215220
const String& name = String::Handle(String::New(TestCase::url()));
216221
const Library& lib = Library::Handle(Library::LookupLibrary(name));
@@ -248,7 +253,8 @@ TEST_CASE(StackmapGC) {
248253
const PcDescriptors& descriptors =
249254
PcDescriptors::Handle(code.pc_descriptors());
250255
int call_count = 0;
251-
PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kUnoptStaticCall);
256+
PcDescriptors::Iterator iter(descriptors,
257+
RawPcDescriptors::kUnoptStaticCall);
252258
while (iter.MoveNext()) {
253259
stackmap_table_builder->AddEntry(iter.PcOffset(), stack_bitmap, 0);
254260
++call_count;

runtime/vm/compiler.cc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,14 +1058,13 @@ bool CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
10581058
// instruction object, since the creation of instruction object
10591059
// changes code page access permissions (makes them temporary not
10601060
// executable).
1061-
isolate()->thread_registry()->SafepointThreads();
10621061
{
1062+
SafepointOperationScope safepoint_scope(thread());
10631063
// Do not Garbage collect during this stage and instead allow the
10641064
// heap to grow.
10651065
NoHeapGrowthControlScope no_growth_control;
10661066
FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
10671067
}
1068-
isolate()->thread_registry()->ResumeAllThreads();
10691068
if (isolate()->heap()->NeedsGarbageCollection()) {
10701069
isolate()->heap()->CollectAllGarbage();
10711070
}
@@ -1899,9 +1898,7 @@ void BackgroundCompiler::Stop(BackgroundCompiler* task) {
18991898
{
19001899
MonitorLocker ml_done(done_monitor);
19011900
while (!(*task_done)) {
1902-
// In case that the compiler is waiting for safepoint.
1903-
Isolate::Current()->thread_registry()->CheckSafepoint();
1904-
ml_done.Wait(1);
1901+
ml_done.WaitWithSafepointCheck(Thread::Current());
19051902
}
19061903
}
19071904
delete task_done;

runtime/vm/compiler_test.cc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@
88
#include "vm/compiler.h"
99
#include "vm/dart_api_impl.h"
1010
#include "vm/object.h"
11+
#include "vm/safepoint.h"
1112
#include "vm/symbols.h"
1213
#include "vm/thread_pool.h"
13-
#include "vm/thread_registry.h"
1414
#include "vm/unit_test.h"
1515

1616
namespace dart {
1717

1818
DECLARE_FLAG(bool, background_compilation);
1919

20-
TEST_CASE(CompileScript) {
20+
VM_TEST_CASE(CompileScript) {
2121
const char* kScriptChars =
2222
"class A {\n"
2323
" static foo() { return 42; }\n"
@@ -32,7 +32,7 @@ TEST_CASE(CompileScript) {
3232
}
3333

3434

35-
TEST_CASE(CompileFunction) {
35+
VM_TEST_CASE(CompileFunction) {
3636
const char* kScriptChars =
3737
"class A {\n"
3838
" static foo() { return 42; }\n"
@@ -73,7 +73,7 @@ TEST_CASE(CompileFunction) {
7373
}
7474

7575

76-
TEST_CASE(CompileFunctionOnHelperThread) {
76+
VM_TEST_CASE(CompileFunctionOnHelperThread) {
7777
// Create a simple function and compile it without optimization.
7878
const char* kScriptChars =
7979
"class A {\n"
@@ -106,8 +106,7 @@ TEST_CASE(CompileFunctionOnHelperThread) {
106106
Monitor* m = new Monitor();
107107
MonitorLocker ml(m);
108108
while (!func.HasOptimizedCode()) {
109-
Isolate::Current()->thread_registry()->CheckSafepoint();
110-
ml.Wait(1);
109+
ml.WaitWithSafepointCheck(thread, 1);
111110
}
112111
BackgroundCompiler::Stop(isolate->background_compiler());
113112
}
@@ -167,6 +166,7 @@ TEST_CASE(EvalExpression) {
167166
Dart_Invoke(lib, Dart_NewStringFromCString("makeObj"), 0, NULL);
168167
EXPECT(!Dart_IsNull(obj_handle));
169168
EXPECT(!Dart_IsError(obj_handle));
169+
TransitionNativeToVM transition(thread);
170170
const Object& obj = Object::Handle(Api::UnwrapHandle(obj_handle));
171171
EXPECT(!obj.IsNull());
172172
EXPECT(obj.IsInstance());
@@ -184,7 +184,7 @@ TEST_CASE(EvalExpression) {
184184
}
185185

186186

187-
TEST_CASE(EvalExpressionWithLazyCompile) {
187+
VM_TEST_CASE(EvalExpressionWithLazyCompile) {
188188
Library& lib = Library::Handle(Library::CoreLibrary());
189189

190190
const String& expression = String::Handle(String::New(
@@ -199,7 +199,7 @@ TEST_CASE(EvalExpressionWithLazyCompile) {
199199
}
200200

201201

202-
TEST_CASE(EvalExpressionExhaustCIDs) {
202+
VM_TEST_CASE(EvalExpressionExhaustCIDs) {
203203
Library& lib = Library::Handle(Library::CoreLibrary());
204204

205205
const String& expression = String::Handle(String::New("3 + 4"));

runtime/vm/coverage_test.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace dart {
1010

1111
static RawObject* ExecuteScript(const char* script) {
12+
TransitionVMToNative transition(Thread::Current());
1213
Dart_Handle h_lib = TestCase::LoadTestScript(script, NULL);
1314
EXPECT_VALID(h_lib);
1415
Library& lib = Library::Handle();
@@ -34,7 +35,7 @@ class FunctionCoverageFilter : public CoverageFilter {
3435
};
3536

3637

37-
TEST_CASE(Coverage_Empty) {
38+
VM_TEST_CASE(Coverage_Empty) {
3839
const char* kScript =
3940
"main() {\n"
4041
"}";
@@ -56,7 +57,7 @@ TEST_CASE(Coverage_Empty) {
5657
}
5758

5859

59-
TEST_CASE(Coverage_MainWithClass) {
60+
VM_TEST_CASE(Coverage_MainWithClass) {
6061
const char* kScript =
6162
"class Foo {\n"
6263
" var x;\n"
@@ -100,7 +101,7 @@ TEST_CASE(Coverage_MainWithClass) {
100101
}
101102

102103

103-
TEST_CASE(Coverage_FilterFunction) {
104+
VM_TEST_CASE(Coverage_FilterFunction) {
104105
const char* kScript =
105106
"class Foo {\n"
106107
" var x;\n"

runtime/vm/custom_isolate_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ static Dart_NativeFunction NativeLookup(Dart_Handle name,
230230
int argc,
231231
bool* auto_setup_scope) {
232232
ASSERT(auto_setup_scope != NULL);
233-
*auto_setup_scope = false;
233+
*auto_setup_scope = true;
234234
const char* name_str = NULL;
235235
EXPECT(Dart_IsString(name));
236236
EXPECT_VALID(Dart_StringToCString(name, &name_str));

0 commit comments

Comments
 (0)