Version 2.18.0-135.0.dev
Merge commit '0f4037b801d18a2a708928ec1be39d224774237b' into 'dev'
diff --git a/DEPS b/DEPS
index 5da3497..58b79b6 100644
--- a/DEPS
+++ b/DEPS
@@ -152,7 +152,7 @@
"sync_http_rev": "b6bd47965694dddffb6e62fb8a6c12d17c4ae4cd",
"term_glyph_rev": "d0f205c67ea70eea47b9f41c8440129a72a9c86e",
"test_descriptor_rev": "ead23c1e7df079ac0f6457a35f7a71432892e527",
- "test_process_rev": "7c73ec8a8a6e0e63d0ec27d70c21ca4323fb5e8f",
+ "test_process_rev": "3e695bcfeab551473ddc288970f345f30e5e1375",
"test_reflective_loader_rev": "fcfce37666672edac849d2af6dffc0f8df236a94",
"test_rev": "d54846bc2b5cfa4e1445fda85c5e48a00940aa68",
"typed_data_rev": "8b19e29bcf4077147de4d67adeabeb48270c65eb",
@@ -163,7 +163,7 @@
"web_socket_channel_rev": "99dbdc5769e19b9eeaf69449a59079153c6a8b1f",
"WebCore_rev": "bcb10901266c884e7b3740abc597ab95373ab55c",
"webdev_rev": "8c814f9d89915418d8abe354ff9befec8f2906b2",
- "webdriver_rev": "ff5ccb1522edf4bed578ead4d65e0cbc1f2c4f02",
+ "webdriver_rev": "e1a9ad671ee82e05eee463f922a34585ed2d2f15",
"webkit_inspection_protocol_rev": "e4965778e2837adc62354eec3a19123402997897",
"yaml_edit_rev": "0b74d85fac10b4fbf7d1a347debcf16c8f7b0e9c",
"yaml_rev": "0971c06490b9670add644ed62182acd6a5536946",
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 0bd5019..5974884 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -439,6 +439,8 @@
/// Handle a [request] that was read from the communication channel.
void handleRequest(Request request) {
+ analyticsManager.startedRequest(
+ request: request, startTime: DateTime.now());
performance.logRequestTiming(request.clientRequestTime);
// Because we don't `await` the execution of the handlers, we wrap the
// execution in order to have one central place to handle exceptions.
@@ -510,6 +512,7 @@
/// Send the given [response] to the client.
void sendResponse(Response response) {
channel.sendResponse(response);
+ analyticsManager.sentResponse(response: response);
cancellationTokens.remove(response.id);
}
diff --git a/pkg/analysis_server/lib/src/handler/legacy/analysis_set_priority_files.dart b/pkg/analysis_server/lib/src/handler/legacy/analysis_set_priority_files.dart
index c8d21c2..90fc2e5 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/analysis_set_priority_files.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/analysis_set_priority_files.dart
@@ -23,6 +23,7 @@
for (var file in params.files) {
if (!server.isAbsoluteAndNormalized(file)) {
sendResponse(Response.invalidFilePathFormat(request, file));
+ return;
}
}
diff --git a/pkg/analysis_server/lib/src/handler/legacy/analysis_update_content.dart b/pkg/analysis_server/lib/src/handler/legacy/analysis_update_content.dart
index b2852185..61f5029 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/analysis_update_content.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/analysis_update_content.dart
@@ -23,6 +23,7 @@
for (var file in params.files.keys) {
if (!server.isAbsoluteAndNormalized(file)) {
sendResponse(Response.invalidFilePathFormat(request, file));
+ return;
}
}
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index 2a54557..bbcd39b 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -343,6 +343,7 @@
/// Handle a [message] that was read from the communication channel.
void handleMessage(Message message) {
+ var startTime = DateTime.now();
performance.logRequestTiming(message.clientRequestTime);
runZonedGuarded(() async {
try {
@@ -367,6 +368,8 @@
);
if (message is RequestMessage) {
+ analyticsManager.startedRequestMessage(
+ request: message, startTime: startTime);
await _handleRequestMessage(message, messageInfo);
} else if (message is NotificationMessage) {
await _handleNotificationMessage(message, messageInfo);
@@ -567,7 +570,7 @@
void sendErrorResponse(Message message, ResponseError error) {
if (message is RequestMessage) {
- channel.sendResponse(ResponseMessage(
+ sendResponse(ResponseMessage(
id: message.id, error: error, jsonrpc: jsonRpcVersion));
} else if (message is ResponseMessage) {
// For bad response messages where we can't respond with an error, send it
@@ -618,6 +621,7 @@
/// Send the given [response] to the client.
void sendResponse(ResponseMessage response) {
channel.sendResponse(response);
+ analyticsManager.sentResponseMessage(response: response);
}
@override
@@ -800,7 +804,7 @@
if (result.isError) {
sendErrorResponse(message, result.error);
} else {
- channel.sendResponse(ResponseMessage(
+ sendResponse(ResponseMessage(
id: message.id,
result: result.result,
jsonrpc: jsonRpcVersion,
diff --git a/pkg/analysis_server/test/analysis/set_priority_files_test.dart b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
index f64c656..6817bb5 100644
--- a/pkg/analysis_server/test/analysis/set_priority_files_test.dart
+++ b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
@@ -28,14 +28,14 @@
Future<void> test_fileDoesNotExist() async {
var file = getFile('$testPackageLibPath/doesNotExist.dart');
var response = await _setPriorityFile(file);
- expect(response, isResponseSuccess('0'));
+ expect(response, isResponseSuccess('1'));
}
Future<void> test_fileInAnalysisRoot() async {
addTestFile('');
// set priority files
var response = await _setPriorityFile(testFile);
- expect(response, isResponseSuccess('0'));
+ expect(response, isResponseSuccess('1'));
// verify
_verifyPriorityFiles(testFile);
}
@@ -55,7 +55,7 @@
.getChildAssumingFolder('convert')
.getChildAssumingFile('convert.dart');
var response = await _setPriorityFile(file);
- expect(response, isResponseSuccess('0'));
+ expect(response, isResponseSuccess('1'));
// verify
_verifyPriorityFiles(file);
}
@@ -116,11 +116,11 @@
var response = await handleRequest(
AnalysisSetPriorityFilesParams([
'test.dart',
- ]).toRequest('0'),
+ ]).toRequest('1'),
);
assertResponseFailure(
response,
- requestId: '0',
+ requestId: '1',
errorCode: RequestErrorCode.INVALID_FILE_PATH_FORMAT,
);
}
@@ -128,10 +128,10 @@
Future<void> test_invalidFilePathFormat_notNormalized() async {
var response = await handleRequest(AnalysisSetPriorityFilesParams([
convertPath('/foo/../bar/test.dart'),
- ]).toRequest('0'));
+ ]).toRequest('1'));
assertResponseFailure(
response,
- requestId: '0',
+ requestId: '1',
errorCode: RequestErrorCode.INVALID_FILE_PATH_FORMAT,
);
}
@@ -140,7 +140,7 @@
addTestFile('');
// set priority files
var response = await _setPriorityFile(testFile);
- expect(response, isResponseSuccess('0'));
+ expect(response, isResponseSuccess('1'));
// verify
var params = pluginManager.analysisSetPriorityFilesParams!;
expect(params.files, [testFile.path]);
@@ -150,7 +150,7 @@
return await handleSuccessfulRequest(
AnalysisSetPriorityFilesParams(<String>[
file.path,
- ]).toRequest('0'),
+ ]).toRequest('1'),
);
}
diff --git a/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart b/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart
index 7dc9690..22bf3ac 100644
--- a/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart
+++ b/runtime/tests/vm/dart/isolates/fast_object_copy_test.dart
@@ -49,12 +49,20 @@
})(),
];
+Uint8List initializeUint8List(Uint8List l) {
+ for (int i = 0; i < l.length; ++i) {
+ l[i] = i % 256;
+ }
+ return l;
+}
+
final Uint8List largeExternalTypedData =
- File(Platform.resolvedExecutable).readAsBytesSync()..[0] = 42;
-final Uint8List largeInternalTypedData = Uint8List(20 * 1024 * 1024)..[0] = 42;
+ initializeUint8List(File(Platform.resolvedExecutable).readAsBytesSync());
+final Uint8List largeInternalTypedData =
+ initializeUint8List(Uint8List(20 * 1024 * 1024));
final Uint8List smallExternalTypedData =
- File(Platform.script.toFilePath()).readAsBytesSync()..[0] = 21;
+ initializeUint8List(File(Platform.script.toFilePath()).readAsBytesSync());
final Uint8List smallExternalTypedDataView =
Uint8List.view(smallExternalTypedData.buffer, 1, 1);
@@ -319,7 +327,7 @@
for (int i = 0; i < 10; ++i) {
final result = await sendReceive(graph);
final etd = result[1];
- Expect.equals(42, etd[0]);
+ expectGraphsMatch(largeExternalTypedData, etd);
}
}
@@ -331,8 +339,8 @@
];
for (int i = 0; i < 10; ++i) {
final result = await sendReceive(graph);
- final etd = result[1];
- Expect.equals(42, etd[0]);
+ final etd = result[0];
+ expectGraphsMatch(largeExternalTypedData, etd);
}
}
@@ -359,7 +367,7 @@
print('testExternalTypedData5');
for (int i = 0; i < 10; ++i) {
final etd = await sendReceive(largeExternalTypedData);
- Expect.equals(42, etd[0]);
+ expectGraphsMatch(largeExternalTypedData, etd);
}
}
@@ -369,8 +377,8 @@
smallExternalTypedData,
largeExternalTypedData,
]);
- Expect.equals(21, etd[0][0]);
- Expect.equals(42, etd[1][0]);
+ expectGraphsMatch(smallExternalTypedData, etd[0]);
+ expectGraphsMatch(largeExternalTypedData, etd[1]);
}
Future testInternalTypedDataView() async {
diff --git a/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart b/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
index fc62573..1e3773d 100644
--- a/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
+++ b/runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
@@ -51,12 +51,20 @@
})(),
];
+Uint8List initializeUint8List(Uint8List l) {
+ for (int i = 0; i < l.length; ++i) {
+ l[i] = i % 256;
+ }
+ return l;
+}
+
final Uint8List largeExternalTypedData =
- File(Platform.resolvedExecutable).readAsBytesSync()..[0] = 42;
-final Uint8List largeInternalTypedData = Uint8List(20 * 1024 * 1024)..[0] = 42;
+ initializeUint8List(File(Platform.resolvedExecutable).readAsBytesSync());
+final Uint8List largeInternalTypedData =
+ initializeUint8List(Uint8List(20 * 1024 * 1024));
final Uint8List smallExternalTypedData =
- File(Platform.script.toFilePath()).readAsBytesSync()..[0] = 21;
+ initializeUint8List(File(Platform.script.toFilePath()).readAsBytesSync());
final Uint8List smallExternalTypedDataView =
Uint8List.view(smallExternalTypedData.buffer, 1, 1);
@@ -321,7 +329,7 @@
for (int i = 0; i < 10; ++i) {
final result = await sendReceive(graph);
final etd = result[1];
- Expect.equals(42, etd[0]);
+ expectGraphsMatch(largeExternalTypedData, etd);
}
}
@@ -333,8 +341,8 @@
];
for (int i = 0; i < 10; ++i) {
final result = await sendReceive(graph);
- final etd = result[1];
- Expect.equals(42, etd[0]);
+ final etd = result[0];
+ expectGraphsMatch(largeExternalTypedData, etd);
}
}
@@ -361,7 +369,7 @@
print('testExternalTypedData5');
for (int i = 0; i < 10; ++i) {
final etd = await sendReceive(largeExternalTypedData);
- Expect.equals(42, etd[0]);
+ expectGraphsMatch(largeExternalTypedData, etd);
}
}
@@ -371,8 +379,8 @@
smallExternalTypedData,
largeExternalTypedData,
]);
- Expect.equals(21, etd[0][0]);
- Expect.equals(42, etd[1][0]);
+ expectGraphsMatch(smallExternalTypedData, etd[0]);
+ expectGraphsMatch(largeExternalTypedData, etd[1]);
}
Future testInternalTypedDataView() async {
diff --git a/runtime/vm/object_graph_copy.cc b/runtime/vm/object_graph_copy.cc
index c49af9a..86d3c8e 100644
--- a/runtime/vm/object_graph_copy.cc
+++ b/runtime/vm/object_graph_copy.cc
@@ -293,6 +293,46 @@
raw_to->data_ = buffer;
}
+template <typename T>
+void CopyTypedDataBaseWithSafepointChecks(Thread* thread,
+ const T& from,
+ const T& to,
+ intptr_t length) {
+ constexpr intptr_t kChunkSize = 100 * 1024;
+
+ const intptr_t chunks = length / kChunkSize;
+ const intptr_t remainder = length % kChunkSize;
+
+ // Notice we re-load the data pointer, since T may be TypedData in which case
+ // the interior pointer may change after checking into safepoints.
+ for (intptr_t i = 0; i < chunks; ++i) {
+ memmove(to.ptr().untag()->data_ + i * kChunkSize,
+ from.ptr().untag()->data_ + i * kChunkSize, kChunkSize);
+
+ thread->CheckForSafepoint();
+ }
+ if (remainder > 0) {
+ memmove(to.ptr().untag()->data_ + chunks * kChunkSize,
+ from.ptr().untag()->data_ + chunks * kChunkSize, remainder);
+ }
+}
+
+void InitializeExternalTypedDataWithSafepointChecks(
+ Thread* thread,
+ intptr_t cid,
+ const ExternalTypedData& from,
+ const ExternalTypedData& to) {
+ const intptr_t length_in_elements = from.Length();
+ const intptr_t length_in_bytes =
+ TypedData::ElementSizeInBytes(cid) * length_in_elements;
+
+ uint8_t* to_data = static_cast<uint8_t*>(malloc(length_in_bytes));
+ to.ptr().untag()->data_ = to_data;
+ to.ptr().untag()->length_ = Smi::New(length_in_elements);
+
+ CopyTypedDataBaseWithSafepointChecks(thread, from, to, length_in_bytes);
+}
+
void InitializeTypedDataView(TypedDataViewPtr obj) {
obj.untag()->typed_data_ = TypedDataBase::null();
obj.untag()->offset_in_bytes_ = 0;
@@ -462,8 +502,10 @@
void AddWeakReference(const WeakReference& from) {
weak_references_.Add(&WeakReference::Handle(from.ptr()));
}
- void AddExternalTypedData(ExternalTypedDataPtr to) {
- external_typed_data_.Add(&ExternalTypedData::Handle(to));
+ const ExternalTypedData& AddExternalTypedData(ExternalTypedDataPtr to) {
+ auto to_handle = &ExternalTypedData::Handle(to);
+ external_typed_data_.Add(to_handle);
+ return *to_handle;
}
void AddObjectToRehash(const Object& to) {
objects_to_rehash_.Add(&Object::Handle(to.ptr()));
@@ -848,6 +890,7 @@
if (Array::UseCardMarkingForAllocation(array_length)) {
for (; offset < end_offset; offset += kCompressedWordSize) {
ForwardCompressedLargeArrayPointer(src, dst, offset);
+ thread_->CheckForSafepoint();
}
} else {
for (; offset < end_offset; offset += kCompressedWordSize) {
@@ -949,9 +992,11 @@
to.untag()->SetCardRememberedBitUnsynchronized();
}
if (IsExternalTypedDataClassId(cid)) {
- InitializeExternalTypedData(cid, ExternalTypedData::RawCast(from.ptr()),
- ExternalTypedData::RawCast(to));
- slow_forward_map_.AddExternalTypedData(ExternalTypedData::RawCast(to));
+ const auto& external_to = slow_forward_map_.AddExternalTypedData(
+ ExternalTypedData::RawCast(to));
+ InitializeExternalTypedDataWithSafepointChecks(
+ thread_, cid, ExternalTypedData::Cast(from), external_to);
+ return external_to.ptr();
} else if (IsTypedDataViewClassId(cid)) {
// We set the views backing store to `null` to satisfy an assertion in
// GCCompactor::VisitTypedDataViewPointers().
@@ -1281,10 +1326,9 @@
#endif
}
- void CopyTypedData(typename Types::TypedData from,
- typename Types::TypedData to) {
- auto raw_from = UntagTypedData(from);
- auto raw_to = UntagTypedData(to);
+ void CopyTypedData(TypedDataPtr from, TypedDataPtr to) {
+ auto raw_from = from.untag();
+ auto raw_to = to.untag();
const intptr_t cid = Types::GetTypedDataPtr(from)->GetClassId();
raw_to->length_ = raw_from->length_;
raw_to->RecomputeDataField();
@@ -1293,6 +1337,17 @@
memmove(raw_to->data_, raw_from->data_, length);
}
+ void CopyTypedData(const TypedData& from, const TypedData& to) {
+ auto raw_from = from.ptr().untag();
+ auto raw_to = to.ptr().untag();
+ const intptr_t cid = Types::GetTypedDataPtr(from)->GetClassId();
+ raw_to->length_ = raw_from->length_;
+ raw_to->RecomputeDataField();
+ const intptr_t length =
+ TypedData::ElementSizeInBytes(cid) * Smi::Value(raw_from->length_);
+ CopyTypedDataBaseWithSafepointChecks(Base::thread_, from, to, length);
+ }
+
void CopyTypedDataView(typename Types::TypedDataView from,
typename Types::TypedDataView to) {
// This will forward & initialize the typed data.
@@ -1457,6 +1512,13 @@
return root_copy;
}
fast_forward_map_.fill_cursor_ += 2;
+
+ // To maintain responsiveness we regularly check whether safepoints are
+ // requested - if so, we bail to slow path which will then checkin.
+ if (thread_->IsSafepointRequested()) {
+ exception_msg_ = kFastAllocationFailed;
+ return root_copy;
+ }
}
// Possibly forward values of [WeakProperty]s if keys became reachable.
@@ -1626,6 +1688,9 @@
if (exception_msg_ != nullptr) {
return Marker();
}
+ // To maintain responsiveness we regularly check whether safepoints are
+ // requested.
+ thread_->CheckForSafepoint();
}
// Possibly forward values of [WeakProperty]s if keys became reachable.
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index f490865..d590114 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2896,6 +2896,13 @@
uint8_t* data_;
private:
+ template <typename T>
+ friend void CopyTypedDataBaseWithSafepointChecks(
+ Thread*,
+ const T&,
+ const T&,
+ intptr_t); // Access _data for memmove with safepoint checkins.
+
RAW_HEAP_OBJECT_IMPLEMENTATION(PointerBase);
};
@@ -2918,6 +2925,11 @@
intptr_t,
ExternalTypedDataPtr,
ExternalTypedDataPtr); // initialize fields.
+ friend void InitializeExternalTypedDataWithSafepointChecks(
+ Thread*,
+ intptr_t,
+ const ExternalTypedData&,
+ const ExternalTypedData&); // initialize fields.
RAW_HEAP_OBJECT_IMPLEMENTATION(TypedDataBase);
};
diff --git a/tools/VERSION b/tools/VERSION
index 39885cb..6d4108b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 134
+PRERELEASE 135
PRERELEASE_PATCH 0
\ No newline at end of file