Version 2.15.0-237.0.dev
Merge commit '6dd4ff6a3b3bd55019622fa00d62c2f385f1a9b6' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.dart
index 16a7d03..61fbebc 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_enum_case_clauses.dart
@@ -12,6 +12,16 @@
class AddMissingEnumCaseClauses extends CorrectionProducer {
@override
+ // Adding the missing case is not a sufficient fix (user logic needs adding
+ // too).
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // Adding the missing case is not a sufficient fix (user logic needs adding
+ // too).
+ bool get canBeAppliedToFile => false;
+
+ @override
FixKind get fixKind => DartFixKind.ADD_MISSING_ENUM_CASE_CLAUSES;
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart
index 4424d19..96e641f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart
@@ -14,6 +14,16 @@
class RemoveDeadIfNull extends CorrectionProducer {
@override
+ // This fix removes the right operand of an if-null which is not predictably
+ // the right thing to do.
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ // This fix removes the right operand of an if-null which is not predictably
+ // the right thing to do.
+ bool get canBeAppliedToFile => false;
+
+ @override
FixKind get fixKind => DartFixKind.REMOVE_IF_NULL_OPERATOR;
@override
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
index b3a9af7..09a3c41 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
@@ -11,9 +11,18 @@
class RemoveUnusedCatchClause extends CorrectionProducer {
@override
+ bool get canBeAppliedInBulk => true;
+
+ @override
+ bool get canBeAppliedToFile => true;
+
+ @override
FixKind get fixKind => DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE;
@override
+ FixKind get multiFixKind => DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE_MULTI;
+
+ @override
Future<void> compute(ChangeBuilder builder) async {
var catchClause = node.parent;
if (catchClause is! CatchClause) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
index 7cdc1ac..1ee1908 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
@@ -11,9 +11,18 @@
class RemoveUnusedCatchStack extends CorrectionProducer {
@override
+ bool get canBeAppliedInBulk => true;
+
+ @override
+ bool get canBeAppliedToFile => true;
+
+ @override
FixKind get fixKind => DartFixKind.REMOVE_UNUSED_CATCH_STACK;
@override
+ FixKind get multiFixKind => DartFixKind.REMOVE_UNUSED_CATCH_STACK_MULTI;
+
+ @override
Future<void> compute(ChangeBuilder builder) async {
var catchClause = node.parent;
if (catchClause is! CatchClause) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index c0f4fbb..e344b12 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -1084,11 +1084,21 @@
DartFixKindPriority.DEFAULT,
"Remove unused 'catch' clause",
);
+ static const REMOVE_UNUSED_CATCH_CLAUSE_MULTI = FixKind(
+ 'dart.fix.remove.unusedCatchClause.multi',
+ DartFixKindPriority.IN_FILE,
+ "Remove unused 'catch' clauses in file",
+ );
static const REMOVE_UNUSED_CATCH_STACK = FixKind(
'dart.fix.remove.unusedCatchStack',
DartFixKindPriority.DEFAULT,
'Remove unused stack trace variable',
);
+ static const REMOVE_UNUSED_CATCH_STACK_MULTI = FixKind(
+ 'dart.fix.remove.unusedCatchStack.multi',
+ DartFixKindPriority.IN_FILE,
+ 'Remove unused stack trace variables in file',
+ );
static const REMOVE_UNUSED_ELEMENT = FixKind(
'dart.fix.remove.unusedElement',
DartFixKindPriority.DEFAULT,
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart
index d18763d..171e2e1 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -11,10 +12,38 @@
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(RemoveUnusedCatchClauseTest);
+ defineReflectiveTests(RemoveUnusedCatchClauseMultiTest);
});
}
@reflectiveTest
+class RemoveUnusedCatchClauseMultiTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE_MULTI;
+
+ Future<void> test_singleFile() async {
+ await resolveTestCode('''
+main() {
+ try {
+ throw 42;
+ } on int catch (i) {
+ } on Error catch (e) {
+ }
+}
+''');
+ await assertHasFixAllFix(HintCode.UNUSED_CATCH_CLAUSE, '''
+main() {
+ try {
+ throw 42;
+ } on int {
+ } on Error {
+ }
+}
+''');
+ }
+}
+
+@reflectiveTest
class RemoveUnusedCatchClauseTest extends FixProcessorTest {
@override
FixKind get kind => DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart
index 730f44e..f72b354 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -11,10 +12,38 @@
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(RemoveUnusedCatchStackTest);
+ defineReflectiveTests(RemoveUnusedCatchStackMultiTest);
});
}
@reflectiveTest
+class RemoveUnusedCatchStackMultiTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNUSED_CATCH_STACK_MULTI;
+
+ Future<void> test_singleFile() async {
+ await resolveTestCode('''
+main() {
+ try {
+ throw 42;
+ } on int catch (i, stack) {
+ } catch (e, stack) {
+ }
+}
+''');
+ await assertHasFixAllFix(HintCode.UNUSED_CATCH_STACK, '''
+main() {
+ try {
+ throw 42;
+ } on int catch (i) {
+ } catch (e) {
+ }
+}
+''');
+ }
+}
+
+@reflectiveTest
class RemoveUnusedCatchStackTest extends FixProcessorTest {
@override
FixKind get kind => DartFixKind.REMOVE_UNUSED_CATCH_STACK;
diff --git a/pkg/analysis_server/tool/bulk_fix/supported_hints.dart b/pkg/analysis_server/tool/bulk_fix/supported_nonlints.dart
similarity index 90%
rename from pkg/analysis_server/tool/bulk_fix/supported_hints.dart
rename to pkg/analysis_server/tool/bulk_fix/supported_nonlints.dart
index ccc3938..e9dcbbc 100644
--- a/pkg/analysis_server/tool/bulk_fix/supported_hints.dart
+++ b/pkg/analysis_server/tool/bulk_fix/supported_nonlints.dart
@@ -13,8 +13,8 @@
print('hints w/ correction producers:\n');
- var hintEntries = FixProcessor.nonLintProducerMap.entries
- .where((e) => e.key.type == ErrorType.HINT);
+ var hintEntries = FixProcessor.nonLintProducerMap.entries.where((e) =>
+ e.key.type == ErrorType.HINT || e.key.type == ErrorType.STATIC_WARNING);
for (var hint in hintEntries) {
var canBeAppliedInBulk = false;
var missingExplanations = <String>[];
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 5665fb5..d605919 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -27,9 +27,8 @@
/// Note that AST units and tokens of [inputLibraries] will be damaged.
LinkResult link(
LinkedElementFactory elementFactory,
- List<LinkInputLibrary> inputLibraries, [
- @Deprecated('Not used anymore') bool? withInformative,
-]) {
+ List<LinkInputLibrary> inputLibraries,
+) {
var linker = Linker(elementFactory);
linker.link(inputLibraries);
return LinkResult(
diff --git a/pkg/analyzer/tool/messages/error_code_info.dart b/pkg/analyzer/tool/messages/error_code_info.dart
index 6ad0667..907a564 100644
--- a/pkg/analyzer/tool/messages/error_code_info.dart
+++ b/pkg/analyzer/tool/messages/error_code_info.dart
@@ -111,14 +111,42 @@
/// two-level map of [ErrorCodeInfo], indexed first by class name and then by
/// error name.
Map<String, Map<String, ErrorCodeInfo>> decodeAnalyzerMessagesYaml(
- Map<Object?, Object?> yaml) {
+ Object? yaml) {
+ Never problem(String message) {
+ throw 'Problem in pkg/analyzer/messages.yaml: $message';
+ }
+
var result = <String, Map<String, ErrorCodeInfo>>{};
+ if (yaml is! Map<Object?, Object?>) {
+ problem('root node is not a map');
+ }
for (var classEntry in yaml.entries) {
- var className = classEntry.key as String;
- for (var errorEntry
- in (classEntry.value as Map<Object?, Object?>).entries) {
- (result[className] ??= {})[errorEntry.key as String] =
- ErrorCodeInfo.fromYaml(errorEntry.value as Map<Object?, Object?>);
+ var className = classEntry.key;
+ if (className is! String) {
+ problem('non-string class key ${json.encode(className)}');
+ }
+ var classValue = classEntry.value;
+ if (classValue is! Map<Object?, Object?>) {
+ problem('value associated with class key $className is not a map');
+ }
+ for (var errorEntry in classValue.entries) {
+ var errorName = errorEntry.key;
+ if (errorName is! String) {
+ problem('in class $className, non-string error key '
+ '${json.encode(errorName)}');
+ }
+ var errorValue = errorEntry.value;
+ if (errorValue is! Map<Object?, Object?>) {
+ problem('value associated with error $className.$errorName is not a '
+ 'map');
+ }
+ try {
+ (result[className] ??= {})[errorName] =
+ ErrorCodeInfo.fromYaml(errorValue);
+ } catch (e) {
+ problem('while processing '
+ '$className.$errorName, $e');
+ }
}
}
return result;
@@ -126,25 +154,39 @@
/// Decodes a YAML object (obtained from `pkg/front_end/messages.yaml`) into a
/// map from error name to [ErrorCodeInfo].
-Map<String, ErrorCodeInfo> decodeCfeMessagesYaml(Map<Object?, Object?> yaml) {
+Map<String, ErrorCodeInfo> decodeCfeMessagesYaml(Object? yaml) {
+ Never problem(String message) {
+ throw 'Problem in pkg/front_end/messages.yaml: $message';
+ }
+
var result = <String, ErrorCodeInfo>{};
+ if (yaml is! Map<Object?, Object?>) {
+ problem('root node is not a map');
+ }
for (var entry in yaml.entries) {
- result[entry.key as String] =
- ErrorCodeInfo.fromYaml(entry.value as Map<Object?, Object?>);
+ var errorName = entry.key;
+ if (errorName is! String) {
+ problem('non-string error key ${json.encode(errorName)}');
+ }
+ var errorValue = entry.value;
+ if (errorValue is! Map<Object?, Object?>) {
+ problem('value associated with error $errorName is not a map');
+ }
+ result[errorName] = ErrorCodeInfo.fromYaml(errorValue);
}
return result;
}
/// Loads analyzer messages from the analyzer's `messages.yaml` file.
Map<String, Map<String, ErrorCodeInfo>> _loadAnalyzerMessages() {
- Map<dynamic, dynamic> messagesYaml =
+ Object? messagesYaml =
loadYaml(File(join(analyzerPkgPath, 'messages.yaml')).readAsStringSync());
return decodeAnalyzerMessagesYaml(messagesYaml);
}
/// Loads front end messages from the front end's `messages.yaml` file.
Map<String, ErrorCodeInfo> _loadFrontEndMessages() {
- Map<dynamic, dynamic> messagesYaml =
+ Object? messagesYaml =
loadYaml(File(join(frontEndPkgPath, 'messages.yaml')).readAsStringSync());
return decodeCfeMessagesYaml(messagesYaml);
}
diff --git a/pkg/dartdev/lib/src/analysis_server.dart b/pkg/dartdev/lib/src/analysis_server.dart
index 0954378..580619b 100644
--- a/pkg/dartdev/lib/src/analysis_server.dart
+++ b/pkg/dartdev/lib/src/analysis_server.dart
@@ -95,7 +95,6 @@
_process = await startDartProcess(sdk, command);
// This callback hookup can't throw.
- // ignore: unawaited_futures
_process.exitCode.whenComplete(() => _process = null);
final Stream<String> errorStream = _process.stderr
@@ -110,7 +109,6 @@
_streamController('server.error').stream.listen(_handleServerError);
- // ignore: unawaited_futures
_sendCommand('server.setSubscriptions', params: <String, dynamic>{
'subscriptions': <String>['STATUS'],
});
@@ -136,7 +134,6 @@
}
});
- // ignore: unawaited_futures
_sendCommand('analysis.setAnalysisRoots', params: <String, dynamic>{
'included': analysisRootPaths,
'excluded': <String>[]
diff --git a/pkg/dartdev/lib/src/commands/analyze.dart b/pkg/dartdev/lib/src/commands/analyze.dart
index 96f0fbe..2c8837b 100644
--- a/pkg/dartdev/lib/src/commands/analyze.dart
+++ b/pkg/dartdev/lib/src/commands/analyze.dart
@@ -128,7 +128,6 @@
bool analysisFinished = false;
- // ignore: unawaited_futures
server.onExit.then((int exitCode) {
if (!analysisFinished) {
io.exitCode = exitCode;
diff --git a/pkg/dartdev/lib/src/commands/fix.dart b/pkg/dartdev/lib/src/commands/fix.dart
index b19b433..c81e467 100644
--- a/pkg/dartdev/lib/src/commands/fix.dart
+++ b/pkg/dartdev/lib/src/commands/fix.dart
@@ -100,7 +100,6 @@
await server.start();
EditBulkFixesResult fixes;
- //ignore: unawaited_futures
server.onExit.then((int exitCode) {
if (fixes == null && exitCode != 0) {
progress?.cancel();
diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc
index a27d27c..e25f0bc 100644
--- a/runtime/vm/app_snapshot.cc
+++ b/runtime/vm/app_snapshot.cc
@@ -3844,14 +3844,9 @@
PushFromTo(type);
- if (type->untag()->type_class_id()->IsHeapObject()) {
- // Type class is still an unresolved class.
- UNREACHABLE();
- }
-
- SmiPtr raw_type_class_id = Smi::RawCast(type->untag()->type_class_id());
+ ASSERT(type->untag()->type_class_id_ != kIllegalCid);
ClassPtr type_class =
- s->isolate_group()->class_table()->At(Smi::Value(raw_type_class_id));
+ s->isolate_group()->class_table()->At(type->untag()->type_class_id_);
s->Push(type_class);
}
@@ -3883,9 +3878,8 @@
// inserted into the canonical_types set.
// Keep in sync with Type::Canonicalize.
virtual bool IsInCanonicalSet(Serializer* s, TypePtr type) {
- SmiPtr raw_type_class_id = Smi::RawCast(type->untag()->type_class_id());
ClassPtr type_class =
- s->isolate_group()->class_table()->At(Smi::Value(raw_type_class_id));
+ s->isolate_group()->class_table()->At(type->untag()->type_class_id_);
if (type_class->untag()->declaration_type() != type) {
return true;
}
@@ -3898,6 +3892,9 @@
void WriteType(Serializer* s, TypePtr type) {
AutoTraceObject(type);
WriteFromTo(type);
+ COMPILE_ASSERT(
+ std::is_unsigned<decltype(UntaggedType::type_class_id_)>::value);
+ s->WriteUnsigned(type->untag()->type_class_id_);
ASSERT(type->untag()->type_state_ < (1 << UntaggedType::kTypeStateBitSize));
ASSERT(type->untag()->nullability_ < (1 << kNullabilityBitSize));
static_assert(UntaggedType::kTypeStateBitSize + kNullabilityBitSize <=
@@ -3934,6 +3931,9 @@
Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
primary && is_canonical());
ReadFromTo(type);
+ COMPILE_ASSERT(
+ std::is_unsigned<decltype(UntaggedType::type_class_id_)>::value);
+ type->untag()->type_class_id_ = d->ReadUnsigned();
const uint8_t combined = d->Read<uint8_t>();
type->untag()->type_state_ = combined >> kNullabilityBitSize;
type->untag()->nullability_ = combined & kNullabilityBitMask;
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index fd3faae..2d58396 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1498,11 +1498,7 @@
Map(param->untag()->parameterized_class_id_);
} else if (obj->IsType()) {
TypePtr type = Type::RawCast(obj);
- ObjectPtr id = type->untag()->type_class_id();
- if (!id->IsHeapObject()) {
- type->untag()->set_type_class_id(
- Smi::New(Map(Smi::Value(Smi::RawCast(id)))));
- }
+ type->untag()->type_class_id_ = Map(type->untag()->type_class_id_);
} else {
intptr_t old_cid = obj->GetClassId();
intptr_t new_cid = Map(old_cid);
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index 8a97dd4..b61046d 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -1360,10 +1360,8 @@
__ b(normal_ir_body, NE);
// Check if types are syntactically equal.
- __ ldr(R3, FieldAddress(R1, target::Type::type_class_id_offset()));
- __ SmiUntag(R3);
- __ ldr(R4, FieldAddress(R2, target::Type::type_class_id_offset()));
- __ SmiUntag(R4);
+ __ LoadTypeClassId(R3, R1);
+ __ LoadTypeClassId(R4, R2);
// We are not testing instance cids, but type class cids of Type instances.
EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
&equiv_cids, ¬_equal, R3, R4, R0,
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index 1b2a819..b6796b5 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -1509,12 +1509,8 @@
__ b(normal_ir_body, NE);
// Check if types are syntactically equal.
- __ LoadCompressedSmi(R3,
- FieldAddress(R1, target::Type::type_class_id_offset()));
- __ SmiUntag(R3);
- __ LoadCompressedSmi(R4,
- FieldAddress(R2, target::Type::type_class_id_offset()));
- __ SmiUntag(R4);
+ __ LoadTypeClassId(R3, R1);
+ __ LoadTypeClassId(R4, R2);
// We are not testing instance cids, but type class cids of Type instances.
EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
&equiv_cids, ¬_equal, R3, R4, R0,
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index 91a1794..0c58ca7 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -1475,10 +1475,8 @@
__ j(NOT_EQUAL, normal_ir_body);
// Check if types are syntactically equal.
- __ movl(ECX, FieldAddress(EDI, target::Type::type_class_id_offset()));
- __ SmiUntag(ECX);
- __ movl(EDX, FieldAddress(EBX, target::Type::type_class_id_offset()));
- __ SmiUntag(EDX);
+ __ LoadTypeClassId(ECX, EDI);
+ __ LoadTypeClassId(EDX, EBX);
// We are not testing instance cids, but type class cids of Type instances.
EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
&equiv_cids, ¬_equal, ECX, EDX, EAX,
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index 0b84166..c4e02a9 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -1380,12 +1380,8 @@
__ j(NOT_EQUAL, normal_ir_body);
// Check if types are syntactically equal.
- __ LoadCompressedSmi(RDI,
- FieldAddress(RCX, target::Type::type_class_id_offset()));
- __ SmiUntag(RDI);
- __ LoadCompressedSmi(RSI,
- FieldAddress(RDX, target::Type::type_class_id_offset()));
- __ SmiUntag(RSI);
+ __ LoadTypeClassId(RDI, RCX);
+ __ LoadTypeClassId(RSI, RDX);
// We are not testing instance cids, but type class cids of Type instances.
EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
&equiv_cids, ¬_equal, RDI, RSI, RAX,
diff --git a/runtime/vm/compiler/assembler/assembler_base.h b/runtime/vm/compiler/assembler/assembler_base.h
index ad8aa79..c3410b4 100644
--- a/runtime/vm/compiler/assembler/assembler_base.h
+++ b/runtime/vm/compiler/assembler/assembler_base.h
@@ -732,6 +732,18 @@
// can be accessed without checking the class id first.
virtual void CompareTypeNullabilityWith(Register type, int8_t value) = 0;
+ void LoadTypeClassId(Register dst, Register src) {
+#if !defined(TARGET_ARCH_IA32)
+ EnsureHasClassIdInDEBUG(kTypeCid, src, TMP);
+#endif
+ ASSERT(!compiler::target::UntaggedType::kTypeClassIdIsSigned);
+ ASSERT_EQUAL(compiler::target::UntaggedType::kTypeClassIdBitSize,
+ kBitsPerInt16);
+ LoadFieldFromOffset(dst, src,
+ compiler::target::Type::type_class_id_offset(),
+ kUnsignedTwoBytes);
+ }
+
virtual void EnsureHasClassIdInDEBUG(intptr_t cid,
Register src,
Register scratch,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 20f828f..a421fe8 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -2520,8 +2520,15 @@
const AbstractType& type,
compiler::Label* is_instance_lbl,
compiler::Label* is_not_instance_lbl) {
+ ASSERT(!type.IsTopTypeForInstanceOf());
__ Comment("InlineInstanceof");
-
+ if (type.IsObjectType()) { // Must be non-nullable.
+ __ CompareObject(TypeTestABI::kInstanceReg, Object::null_object());
+ // All non-null objects are instances of non-nullable Object.
+ __ BranchIf(NOT_EQUAL, is_instance_lbl);
+ __ Jump(is_not_instance_lbl);
+ return SubtypeTestCache::null(); // No need for an STC.
+ }
if (type.IsFunctionType()) {
return GenerateFunctionTypeTest(source, type, is_instance_lbl,
is_not_instance_lbl);
@@ -2577,6 +2584,11 @@
const Class& type_class,
compiler::Label* is_instance_lbl,
compiler::Label* is_not_instance_lbl) {
+ // If the type being tested is non-nullable Object, we are in NNBD strong
+ // mode, since top types do not reach here. In this case, testing the
+ // superclass of a null instance yields a wrong result (as the Null class
+ // extends Object).
+ ASSERT(!type_class.IsObjectClass());
__ Comment("Subtype1TestCacheLookup");
#if defined(DEBUG)
compiler::Label ok;
@@ -2584,43 +2596,40 @@
__ Breakpoint();
__ Bind(&ok);
#endif
- // Check immediate superclass equality. If type_class is Object, then testing
- // supertype may yield a wrong result for Null in NNBD strong mode (because
- // Null also extends Object).
- if (!type_class.IsObjectClass() ||
- !IsolateGroup::Current()->use_strict_null_safety_checks()) {
- // We don't use TypeTestABI::kScratchReg for the first scratch register as
- // it is not defined on IA32. Instead, we use the subtype test cache
- // register, as it is clobbered by the subtype test cache stub call anyway.
- const Register kScratch1Reg = TypeTestABI::kSubtypeTestCacheReg;
+ // We don't use TypeTestABI::kScratchReg for the first scratch register as
+ // it is not defined on IA32. Instead, we use the subtype test cache
+ // register, as it is clobbered by the subtype test cache stub call anyway.
+ const Register kScratch1Reg = TypeTestABI::kSubtypeTestCacheReg;
#if defined(TARGET_ARCH_IA32)
- // We don't use TypeTestABI::kScratchReg as it is not defined on IA32.
- // Instead, we pick another TypeTestABI register and push/pop it around
- // the uses of the second scratch register.
- const Register kScratch2Reg = TypeTestABI::kDstTypeReg;
- __ PushRegister(kScratch2Reg);
+ // We don't use TypeTestABI::kScratchReg as it is not defined on IA32.
+ // Instead, we pick another TypeTestABI register and push/pop it around
+ // the uses of the second scratch register.
+ const Register kScratch2Reg = TypeTestABI::kDstTypeReg;
+ __ PushRegister(kScratch2Reg);
#else
- // We can use TypeTestABI::kScratchReg for the second scratch register, as
- // IA32 is handled separately.
- const Register kScratch2Reg = TypeTestABI::kScratchReg;
+ // We can use TypeTestABI::kScratchReg for the second scratch register, as
+ // IA32 is handled separately.
+ const Register kScratch2Reg = TypeTestABI::kScratchReg;
#endif
- static_assert(kScratch1Reg != kScratch2Reg,
- "Scratch registers must be distinct");
- __ LoadClassId(kScratch2Reg, TypeTestABI::kInstanceReg);
- __ LoadClassById(kScratch1Reg, kScratch2Reg);
+ static_assert(kScratch1Reg != kScratch2Reg,
+ "Scratch registers must be distinct");
+ // Check immediate superclass equality.
+ __ LoadClassId(kScratch2Reg, TypeTestABI::kInstanceReg);
+ __ LoadClassById(kScratch1Reg, kScratch2Reg);
#if defined(TARGET_ARCH_IA32)
- // kScratch2 is no longer used, so restore it.
- __ PopRegister(kScratch2Reg);
+ // kScratch2 is no longer used, so restore it.
+ __ PopRegister(kScratch2Reg);
#endif
- __ LoadCompressedFieldFromOffset(
- kScratch1Reg, kScratch1Reg,
- compiler::target::Class::super_type_offset());
- __ LoadCompressedFieldFromOffset(
- kScratch1Reg, kScratch1Reg,
- compiler::target::Type::type_class_id_offset());
- __ CompareImmediate(kScratch1Reg, Smi::RawValue(type_class.id()));
- __ BranchIf(EQUAL, is_instance_lbl);
- }
+ __ LoadCompressedFieldFromOffset(
+ kScratch1Reg, kScratch1Reg, compiler::target::Class::super_type_offset());
+ // Check for a null super type. Instances whose class has a null super type
+ // can only be an instance of top types or of non-nullable Object, but this
+ // method is not called for those types, so the object cannot be an instance.
+ __ CompareObject(kScratch1Reg, Object::null_object());
+ __ BranchIf(EQUAL, is_not_instance_lbl);
+ __ LoadTypeClassId(kScratch1Reg, kScratch1Reg);
+ __ CompareImmediate(kScratch1Reg, type_class.id());
+ __ BranchIf(EQUAL, is_instance_lbl);
return GenerateCallSubtypeTestStub(kTestTypeOneArg, is_instance_lbl,
is_not_instance_lbl);
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 5bc2fff..3210c35 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -369,6 +369,12 @@
const word UntaggedAbstractType::kTypeStateFinalizedInstantiated =
dart::UntaggedAbstractType::kFinalizedInstantiated;
+const bool UntaggedType::kTypeClassIdIsSigned =
+ std::is_signed<decltype(dart::UntaggedType::type_class_id_)>::value;
+
+const word UntaggedType::kTypeClassIdBitSize =
+ sizeof(dart::UntaggedType::type_class_id_) * kBitsPerByte;
+
const word UntaggedObject::kBarrierOverlapShift =
dart::UntaggedObject::kBarrierOverlapShift;
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 85c8181..5ce613d 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -451,6 +451,12 @@
static const word kTypeStateFinalizedInstantiated;
};
+class UntaggedType : public AllStatic {
+ public:
+ static const bool kTypeClassIdIsSigned;
+ static const word kTypeClassIdBitSize;
+};
+
class Object : public AllStatic {
public:
// Offset of the tags word.
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 8a16d29..494a811 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -419,11 +419,11 @@
Thread_callback_stack_return_offset = 780;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word Type_hash_offset = 20;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
-static constexpr dart::compiler::target::word Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word Type_nullability_offset = 25;
+static constexpr dart::compiler::target::word Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word Type_hash_offset = 16;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word Type_nullability_offset = 23;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 24;
@@ -549,7 +549,7 @@
static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word Type_InstanceSize = 24;
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
@@ -977,11 +977,11 @@
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 32;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
+static constexpr dart::compiler::target::word Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word Type_nullability_offset = 43;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 48;
@@ -1109,7 +1109,7 @@
static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 48;
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -1528,11 +1528,11 @@
Thread_callback_stack_return_offset = 748;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word Type_hash_offset = 20;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
-static constexpr dart::compiler::target::word Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word Type_nullability_offset = 25;
+static constexpr dart::compiler::target::word Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word Type_hash_offset = 16;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word Type_nullability_offset = 23;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 24;
@@ -1655,7 +1655,7 @@
static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word Type_InstanceSize = 24;
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
@@ -2083,11 +2083,11 @@
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 32;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
+static constexpr dart::compiler::target::word Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word Type_nullability_offset = 43;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 48;
@@ -2216,7 +2216,7 @@
static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 48;
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -2641,11 +2641,11 @@
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word Type_nullability_offset = 37;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
+static constexpr dart::compiler::target::word Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word Type_nullability_offset = 35;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 36;
@@ -3198,11 +3198,11 @@
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word Type_nullability_offset = 37;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
+static constexpr dart::compiler::target::word Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word Type_nullability_offset = 35;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 36;
@@ -3746,11 +3746,11 @@
Thread_callback_stack_return_offset = 780;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word Type_hash_offset = 20;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
-static constexpr dart::compiler::target::word Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word Type_nullability_offset = 25;
+static constexpr dart::compiler::target::word Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word Type_hash_offset = 16;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word Type_nullability_offset = 23;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 24;
@@ -3876,7 +3876,7 @@
static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word Type_InstanceSize = 24;
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
@@ -4298,11 +4298,11 @@
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 32;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
+static constexpr dart::compiler::target::word Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word Type_nullability_offset = 43;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 48;
@@ -4430,7 +4430,7 @@
static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 48;
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -4843,11 +4843,11 @@
Thread_callback_stack_return_offset = 748;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word Type_hash_offset = 20;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
-static constexpr dart::compiler::target::word Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word Type_nullability_offset = 25;
+static constexpr dart::compiler::target::word Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word Type_hash_offset = 16;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 20;
+static constexpr dart::compiler::target::word Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word Type_nullability_offset = 23;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 24;
@@ -4970,7 +4970,7 @@
static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 20;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word Type_InstanceSize = 24;
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 28;
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 16;
@@ -5392,11 +5392,11 @@
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word Type_hash_offset = 40;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word Type_nullability_offset = 49;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 32;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 40;
+static constexpr dart::compiler::target::word Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word Type_nullability_offset = 43;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 48;
@@ -5525,7 +5525,7 @@
static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word Type_InstanceSize = 48;
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 48;
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
@@ -5944,11 +5944,11 @@
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word Type_nullability_offset = 37;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
+static constexpr dart::compiler::target::word Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word Type_nullability_offset = 35;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 36;
@@ -6495,11 +6495,11 @@
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word Type_hash_offset = 32;
-static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
-static constexpr dart::compiler::target::word Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word Type_nullability_offset = 37;
+static constexpr dart::compiler::target::word Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Type_hash_offset = 28;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 32;
+static constexpr dart::compiler::target::word Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word Type_nullability_offset = 35;
static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
static constexpr dart::compiler::target::word
FunctionType_named_parameter_names_offset = 36;
@@ -7092,12 +7092,12 @@
AOT_TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
12;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 20;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 16;
static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
- 12;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 25;
+ 20;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 23;
static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 28;
static constexpr dart::compiler::target::word
AOT_FunctionType_named_parameter_names_offset = 24;
@@ -7242,7 +7242,7 @@
static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 20;
static constexpr dart::compiler::target::word
AOT_TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
28;
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -7710,12 +7710,12 @@
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
- 24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
+ 40;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
static constexpr dart::compiler::target::word
AOT_FunctionType_named_parameter_names_offset = 48;
@@ -7862,7 +7862,7 @@
static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
static constexpr dart::compiler::target::word
AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
48;
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -8333,12 +8333,12 @@
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
- 24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
+ 40;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
static constexpr dart::compiler::target::word
AOT_FunctionType_named_parameter_names_offset = 48;
@@ -8486,7 +8486,7 @@
static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
static constexpr dart::compiler::target::word
AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
48;
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -8953,12 +8953,12 @@
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
- 24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
+ 32;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
static constexpr dart::compiler::target::word
AOT_FunctionType_named_parameter_names_offset = 36;
@@ -9572,12 +9572,12 @@
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
- 24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
+ 32;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
static constexpr dart::compiler::target::word
AOT_FunctionType_named_parameter_names_offset = 36;
@@ -10186,12 +10186,12 @@
AOT_TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
12;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 16;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 20;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 12;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 16;
static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
- 12;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 24;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 25;
+ 20;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 22;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 23;
static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 28;
static constexpr dart::compiler::target::word
AOT_FunctionType_named_parameter_names_offset = 24;
@@ -10336,7 +10336,7 @@
static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 20;
static constexpr dart::compiler::target::word
AOT_TransferableTypedData_InstanceSize = 4;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 28;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
28;
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -10797,12 +10797,12 @@
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
- 24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
+ 40;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
static constexpr dart::compiler::target::word
AOT_FunctionType_named_parameter_names_offset = 48;
@@ -10949,7 +10949,7 @@
static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
static constexpr dart::compiler::target::word
AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
48;
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -11413,12 +11413,12 @@
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
- 24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 48;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
+ 40;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 42;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 43;
static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
static constexpr dart::compiler::target::word
AOT_FunctionType_named_parameter_names_offset = 48;
@@ -11566,7 +11566,7 @@
static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
static constexpr dart::compiler::target::word
AOT_TransferableTypedData_InstanceSize = 8;
-static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 56;
+static constexpr dart::compiler::target::word AOT_Type_InstanceSize = 48;
static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
48;
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
@@ -12026,12 +12026,12 @@
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
- 24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
+ 32;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
static constexpr dart::compiler::target::word
AOT_FunctionType_named_parameter_names_offset = 36;
@@ -12638,12 +12638,12 @@
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
16;
-static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 28;
-static constexpr dart::compiler::target::word AOT_Type_hash_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 28;
static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
- 24;
-static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 36;
-static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
+ 32;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 34;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 35;
static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
static constexpr dart::compiler::target::word
AOT_FunctionType_named_parameter_names_offset = 36;
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index c340571..210001c 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -322,11 +322,7 @@
// instantiation may result in a top type.
// Function types cannot be top types.
__ BranchIf(NOT_EQUAL, &done);
- __ LoadCompressedField(
- scratch2_reg,
- compiler::FieldAddress(scratch1_reg,
- compiler::target::Type::type_class_id_offset()));
- __ SmiUntag(scratch2_reg);
+ __ LoadTypeClassId(scratch2_reg, scratch1_reg);
__ CompareImmediate(scratch2_reg, kDynamicCid);
__ BranchIf(EQUAL, &is_top_type, compiler::Assembler::kNearJump);
__ CompareImmediate(scratch2_reg, kVoidCid);
@@ -443,11 +439,7 @@
// FutureOr is a special case because it may have the non-nullable bit set,
// but FutureOr<T> functions as the union of T and Future<T>, so it must be
// unwrapped to see if T is nullable.
- __ LoadCompressedField(
- kScratchReg,
- compiler::FieldAddress(kCurrentTypeReg,
- compiler::target::Type::type_class_id_offset()));
- __ SmiUntag(kScratchReg);
+ __ LoadTypeClassId(kScratchReg, kCurrentTypeReg);
__ CompareImmediate(kScratchReg, kFutureOrCid);
__ BranchIf(NOT_EQUAL, &done);
__ LoadCompressedField(
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index aeca374..cf8f107 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -20690,7 +20690,7 @@
}
classid_t Type::type_class_id() const {
- return Smi::Value(untag()->type_class_id());
+ return untag()->type_class_id_;
}
ClassPtr Type::type_class() const {
@@ -21261,16 +21261,7 @@
void Type::set_type_class(const Class& value) const {
ASSERT(!value.IsNull());
- const intptr_t id = value.id();
- // We should never need a Type object for a top-level class.
- ASSERT(!ClassTable::IsTopLevelCid(id));
- ASSERT(id == kIllegalCid || !IsInternalOnlyClassId(id));
- // We must allow Types with kIllegalCid type class ids, because the class
- // used for evaluating expressions inside a instance method call context
- // from the debugger is not registered (and thus has kIllegalCid as an id).
- // Thus, we check id != kIllegalCid only if IsType(), not if and only if.
- ASSERT(id == kIllegalCid || IsType());
- untag()->set_type_class_id(Smi::New(id));
+ set_type_class_id(value.id());
}
void Type::set_arguments(const TypeArguments& value) const {
@@ -21302,6 +21293,19 @@
return result.ptr();
}
+void Type::set_type_class_id(intptr_t id) const {
+ COMPILE_ASSERT(
+ std::is_unsigned<decltype(UntaggedType::type_class_id_)>::value);
+ ASSERT(Utils::IsUint(sizeof(untag()->type_class_id_) * kBitsPerByte, id));
+ // We should never need a Type object for a top-level class.
+ ASSERT(!ClassTable::IsTopLevelCid(id));
+ // We must allow Types with kIllegalCid type class ids, because the class
+ // used for evaluating expressions inside a instance method call context
+ // from the debugger is not registered (and thus has kIllegalCid as an id).
+ ASSERT(id == kIllegalCid || !IsInternalOnlyClassId(id));
+ StoreNonPointer(&untag()->type_class_id_, id);
+}
+
void Type::set_type_state(uint8_t state) const {
ASSERT(state <= UntaggedType::kFinalizedUninstantiated);
StoreNonPointer(&untag()->type_state_, state);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 2ef9d1d..ad0d7cd 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -8417,6 +8417,10 @@
private:
void SetHash(intptr_t value) const;
+ // Takes an intptr_t since the cids of some classes are larger than will fit
+ // in ClassIdTagType. This allows us to guard against that case, instead of
+ // silently truncating the cid.
+ void set_type_class_id(intptr_t id) const;
void set_type_state(uint8_t state) const;
void set_nullability(Nullability value) const {
ASSERT(!IsCanonical());
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index b1019e8..1f6a0e3 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -305,8 +305,9 @@
friend class IsolateGroup; // to access set_thread(Thread*).
friend class OSThreadIterator;
- friend class ThreadInterrupterWin;
friend class ThreadInterrupterFuchsia;
+ friend class ThreadInterrupterMacOS;
+ friend class ThreadInterrupterWin;
friend class ThreadPool; // to access owning_thread_pool_worker_
};
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index ae7d7a9..986cb2d 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2520,15 +2520,16 @@
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(Type);
- COMPRESSED_POINTER_FIELD(SmiPtr, type_class_id)
COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, arguments)
COMPRESSED_POINTER_FIELD(SmiPtr, hash)
VISIT_TO(hash)
+ ClassIdTagType type_class_id_;
uint8_t type_state_;
uint8_t nullability_;
CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+ friend class compiler::target::UntaggedType;
friend class CidRewriteVisitor;
friend class UntaggedTypeArguments;
};
diff --git a/runtime/vm/signal_handler_macos.cc b/runtime/vm/signal_handler_macos.cc
index 70e5319..0e0c591 100644
--- a/runtime/vm/signal_handler_macos.cc
+++ b/runtime/vm/signal_handler_macos.cc
@@ -91,24 +91,11 @@
}
void SignalHandler::Install(SignalAction action) {
- struct sigaction act = {};
- act.sa_handler = NULL;
- act.sa_sigaction = action;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_RESTART | SA_SIGINFO;
- int r = sigaction(SIGPROF, &act, NULL);
- ASSERT(r == 0);
+ // Nothing to do on MacOS.
}
void SignalHandler::Remove() {
- // Ignore future SIGPROF signals because by default SIGPROF will terminate
- // the process and we may have some signals in flight.
- struct sigaction act = {};
- act.sa_handler = SIG_IGN;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- int r = sigaction(SIGPROF, &act, NULL);
- ASSERT(r == 0);
+ // Nothing to do on MacOS.
}
} // namespace dart
diff --git a/runtime/vm/thread_interrupter.cc b/runtime/vm/thread_interrupter.cc
index be990ab..978b428 100644
--- a/runtime/vm/thread_interrupter.cc
+++ b/runtime/vm/thread_interrupter.cc
@@ -66,15 +66,6 @@
void ThreadInterrupter::Startup() {
ASSERT(initialized_);
- if (IsDebuggerAttached()) {
- MonitorLocker shutdown_ml(monitor_);
- shutdown_ = true;
- if (FLAG_trace_thread_interrupter) {
- OS::PrintErr(
- "ThreadInterrupter disabled because a debugger is attached.\n");
- }
- return;
- }
if (FLAG_trace_thread_interrupter) {
OS::PrintErr("ThreadInterrupter starting up.\n");
}
diff --git a/runtime/vm/thread_interrupter.h b/runtime/vm/thread_interrupter.h
index c5d770e..8921ebe 100644
--- a/runtime/vm/thread_interrupter.h
+++ b/runtime/vm/thread_interrupter.h
@@ -102,8 +102,6 @@
static std::atomic<intptr_t> sample_buffer_lock_;
static std::atomic<intptr_t> sample_buffer_waiters_;
- static bool IsDebuggerAttached();
-
static bool InDeepSleep() {
return current_wait_time_ == Monitor::kNoTimeout;
}
diff --git a/runtime/vm/thread_interrupter_android.cc b/runtime/vm/thread_interrupter_android.cc
index dbdd331..2f8ed98 100644
--- a/runtime/vm/thread_interrupter_android.cc
+++ b/runtime/vm/thread_interrupter_android.cc
@@ -61,10 +61,6 @@
#endif
} // namespace
-bool ThreadInterrupter::IsDebuggerAttached() {
- return false;
-}
-
void ThreadInterrupter::InterruptThread(OSThread* thread) {
if (FLAG_trace_thread_interrupter) {
OS::PrintErr("ThreadInterrupter interrupting %p\n",
diff --git a/runtime/vm/thread_interrupter_fuchsia.cc b/runtime/vm/thread_interrupter_fuchsia.cc
index b295569..235bbed 100644
--- a/runtime/vm/thread_interrupter_fuchsia.cc
+++ b/runtime/vm/thread_interrupter_fuchsia.cc
@@ -227,10 +227,6 @@
}
};
-bool ThreadInterrupter::IsDebuggerAttached() {
- return false;
-}
-
void ThreadInterrupter::InterruptThread(OSThread* thread) {
if (FLAG_trace_thread_interrupter) {
OS::PrintErr("ThreadInterrupter suspending %p\n",
diff --git a/runtime/vm/thread_interrupter_linux.cc b/runtime/vm/thread_interrupter_linux.cc
index ee623db..5d7661d 100644
--- a/runtime/vm/thread_interrupter_linux.cc
+++ b/runtime/vm/thread_interrupter_linux.cc
@@ -48,10 +48,6 @@
}
};
-bool ThreadInterrupter::IsDebuggerAttached() {
- return false;
-}
-
void ThreadInterrupter::InterruptThread(OSThread* thread) {
if (FLAG_trace_thread_interrupter) {
OS::PrintErr("ThreadInterrupter interrupting %p\n",
diff --git a/runtime/vm/thread_interrupter_macos.cc b/runtime/vm/thread_interrupter_macos.cc
index ba9ce5a..9676b53 100644
--- a/runtime/vm/thread_interrupter_macos.cc
+++ b/runtime/vm/thread_interrupter_macos.cc
@@ -5,12 +5,15 @@
#include "platform/globals.h"
#if defined(DART_HOST_OS_MACOS)
-#include <assert.h> // NOLINT
-#include <errno.h> // NOLINT
-#include <stdbool.h> // NOLINT
-#include <sys/sysctl.h> // NOLINT
-#include <sys/types.h> // NOLINT
-#include <unistd.h> // NOLINT
+#include <assert.h> // NOLINT
+#include <errno.h> // NOLINT
+#include <mach/kern_return.h> // NOLINT
+#include <mach/mach.h> // NOLINT
+#include <mach/thread_act.h> // NOLINT
+#include <stdbool.h> // NOLINT
+#include <sys/sysctl.h> // NOLINT
+#include <sys/types.h> // NOLINT
+#include <unistd.h> // NOLINT
#include "vm/flags.h"
#include "vm/os.h"
@@ -24,70 +27,110 @@
DECLARE_FLAG(bool, trace_thread_interrupter);
-// Returns true if the current process is being debugged (either
-// running under the debugger or has a debugger attached post facto).
-// Code from https://developer.apple.com/library/content/qa/qa1361/_index.html
-bool ThreadInterrupter::IsDebuggerAttached() {
- struct kinfo_proc info;
- // Initialize the flags so that, if sysctl fails for some bizarre
- // reason, we get a predictable result.
- info.kp_proc.p_flag = 0;
- // Initialize mib, which tells sysctl the info we want, in this case
- // we're looking for information about a specific process ID.
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
- size_t size = sizeof(info);
+#if defined(HOST_ARCH_X64)
+#define THREAD_STATE_FLAVOR x86_THREAD_STATE64
+#define THREAD_STATE_FLAVOR_SIZE x86_THREAD_STATE64_COUNT
+typedef x86_thread_state64_t thread_state_flavor_t;
+#elif defined(HOST_ARCH_ARM64)
+#define THREAD_STATE_FLAVOR ARM_THREAD_STATE64
+#define THREAD_STATE_FLAVOR_SIZE ARM_THREAD_STATE64_COUNT
+typedef arm_thread_state64_t thread_state_flavor_t;
+#elif defined(HOST_ARCH_ARM)
+#define THREAD_STATE_FLAVOR ARM_THREAD_STATE32
+#define THREAD_STATE_FLAVOR_SIZE ARM_THREAD_STATE32_COUNT
+typedef arm_thread_state32_t thread_state_flavor_t;
+#else
+#error "Unsupported architecture."
+#endif // HOST_ARCH_...
- // Call sysctl.
- size = sizeof(info);
- int junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
- ASSERT(junk == 0);
- // We're being debugged if the P_TRACED flag is set.
- return ((info.kp_proc.p_flag & P_TRACED) != 0);
-}
-
-class ThreadInterrupterMacOS : public AllStatic {
+class ThreadInterrupterMacOS {
public:
- static void ThreadInterruptSignalHandler(int signal,
- siginfo_t* info,
- void* context_) {
- if (signal != SIGPROF) {
- return;
- }
- Thread* thread = Thread::Current();
- if (thread == NULL) {
- return;
- }
- ThreadInterrupter::SampleBufferWriterScope scope;
- if (!scope.CanSample()) {
- return;
- }
- // Extract thread state.
- ucontext_t* context = reinterpret_cast<ucontext_t*>(context_);
- mcontext_t mcontext = context->uc_mcontext;
- InterruptedThreadState its;
- its.pc = SignalHandler::GetProgramCounter(mcontext);
- its.fp = SignalHandler::GetFramePointer(mcontext);
- its.csp = SignalHandler::GetCStackPointer(mcontext);
- its.dsp = SignalHandler::GetDartStackPointer(mcontext);
- its.lr = SignalHandler::GetLinkRegister(mcontext);
- Profiler::SampleThread(thread, its);
+ explicit ThreadInterrupterMacOS(OSThread* os_thread) : os_thread_(os_thread) {
+ ASSERT(os_thread != nullptr);
+ mach_thread_ = pthread_mach_thread_np(os_thread->id());
+ ASSERT(reinterpret_cast<void*>(mach_thread_) != nullptr);
+ res = thread_suspend(mach_thread_);
}
+
+ void CollectSample() {
+ if (res != KERN_SUCCESS) {
+ return;
+ }
+ auto count = static_cast<mach_msg_type_number_t>(THREAD_STATE_FLAVOR_SIZE);
+ thread_state_flavor_t state;
+ kern_return_t res =
+ thread_get_state(mach_thread_, THREAD_STATE_FLAVOR,
+ reinterpret_cast<thread_state_t>(&state), &count);
+ ASSERT(res == KERN_SUCCESS);
+ Thread* thread = static_cast<Thread*>(os_thread_->thread());
+ if (thread == nullptr) {
+ return;
+ }
+ Profiler::SampleThread(thread, ProcessState(state));
+ }
+
+ ~ThreadInterrupterMacOS() {
+ if (res != KERN_SUCCESS) {
+ return;
+ }
+ res = thread_resume(mach_thread_);
+ ASSERT(res == KERN_SUCCESS);
+ }
+
+ private:
+ static InterruptedThreadState ProcessState(thread_state_flavor_t state) {
+ InterruptedThreadState its;
+#if defined(HOST_ARCH_X64)
+ its.pc = state.__rip;
+ its.fp = state.__rbp;
+ its.csp = state.__rsp;
+ its.dsp = state.__rsp;
+ its.lr = 0;
+#elif defined(HOST_ARCH_ARM64)
+ its.pc = state.__pc;
+ its.fp = state.__fp;
+ its.csp = state.__sp;
+ its.dsp = state.__sp;
+ its.lr = state.__lr;
+#elif defined(HOST_ARCH_ARM)
+ its.pc = state.__pc;
+ its.fp = state.__r[7];
+ its.csp = state.__sp;
+ its.dsp = state.__sp;
+ its.lr = state.__lr;
+#endif // HOST_ARCH_...
+
+#if defined(TARGET_ARCH_ARM64) && !defined(USING_SIMULATOR)
+ its.dsp = state.__x[SPREG];
+#endif
+ return its;
+ }
+
+ kern_return_t res;
+ OSThread* os_thread_;
+ mach_port_t mach_thread_;
};
-void ThreadInterrupter::InterruptThread(OSThread* thread) {
+void ThreadInterrupter::InterruptThread(OSThread* os_thread) {
+ ASSERT(!OSThread::Compare(OSThread::GetCurrentThreadId(), os_thread->id()));
if (FLAG_trace_thread_interrupter) {
- OS::PrintErr("ThreadInterrupter interrupting %p\n", thread->id());
+ OS::PrintErr("ThreadInterrupter interrupting %p\n", os_thread->id());
}
- int result = pthread_kill(thread->id(), SIGPROF);
- ASSERT((result == 0) || (result == ESRCH));
+
+ ThreadInterrupter::SampleBufferWriterScope scope;
+ if (!scope.CanSample()) {
+ return;
+ }
+ ThreadInterrupterMacOS interrupter(os_thread);
+ interrupter.CollectSample();
}
void ThreadInterrupter::InstallSignalHandler() {
- SignalHandler::Install(&ThreadInterrupterMacOS::ThreadInterruptSignalHandler);
+ // Nothing to do on MacOS.
}
void ThreadInterrupter::RemoveSignalHandler() {
- SignalHandler::Remove();
+ // Nothing to do on MacOS.
}
#endif // !PRODUCT
diff --git a/runtime/vm/thread_interrupter_win.cc b/runtime/vm/thread_interrupter_win.cc
index bfbf5d1..3db5023 100644
--- a/runtime/vm/thread_interrupter_win.cc
+++ b/runtime/vm/thread_interrupter_win.cc
@@ -90,10 +90,6 @@
}
};
-bool ThreadInterrupter::IsDebuggerAttached() {
- return false;
-}
-
void ThreadInterrupter::InterruptThread(OSThread* thread) {
if (FLAG_trace_thread_interrupter) {
OS::PrintErr("ThreadInterrupter suspending %p\n",
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index 5742615..6b1780f 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -996,18 +996,6 @@
}
}
-// src must contain a TypePtr. Assumes dst != src. May affect flags.
-static void LoadTypeClassId(compiler::Assembler* assembler,
- Register dst,
- Register src) {
- ASSERT(src != dst);
- __ EnsureHasClassIdInDEBUG(kTypeCid, src, dst);
- __ LoadCompressedSmi(
- dst, compiler::FieldAddress(
- src, compiler::target::Type::type_class_id_offset()));
- __ SmiUntag(dst);
-}
-
void TypeTestingStubGenerator::BuildOptimizedTypeParameterArgumentValueCheck(
compiler::Assembler* assembler,
HierarchyInfo* hi,
@@ -1052,8 +1040,8 @@
UnwrapAbstractType(assembler, TTSInternalRegs::kSuperTypeArgumentReg,
TTSInternalRegs::kScratchReg, /*is_type=*/nullptr,
&check_subtype_type_class_ids);
- LoadTypeClassId(assembler, TTSInternalRegs::kScratchReg,
- TTSInternalRegs::kSuperTypeArgumentReg);
+ __ LoadTypeClassId(TTSInternalRegs::kScratchReg,
+ TTSInternalRegs::kSuperTypeArgumentReg);
__ CompareImmediate(TTSInternalRegs::kScratchReg, kDynamicCid);
__ BranchIf(EQUAL, &is_subtype);
__ CompareImmediate(TTSInternalRegs::kScratchReg, kVoidCid);
@@ -1090,8 +1078,8 @@
UnwrapAbstractType(assembler, TTSInternalRegs::kSubTypeArgumentReg,
TTSInternalRegs::kScratchReg, /*is_type=*/nullptr,
check_failed);
- LoadTypeClassId(assembler, TTSInternalRegs::kScratchReg,
- TTSInternalRegs::kSubTypeArgumentReg);
+ __ LoadTypeClassId(TTSInternalRegs::kScratchReg,
+ TTSInternalRegs::kSubTypeArgumentReg);
__ CompareImmediate(TTSInternalRegs::kScratchReg, kNeverCid);
__ BranchIf(EQUAL, &is_subtype);
__ CompareImmediate(TTSInternalRegs::kScratchReg, kNullCid);
@@ -1186,8 +1174,8 @@
// No further checks needed for non-nullable object.
if (!type.IsObjectType()) {
- LoadTypeClassId(assembler, TTSInternalRegs::kScratchReg,
- TTSInternalRegs::kSubTypeArgumentReg);
+ __ LoadTypeClassId(TTSInternalRegs::kScratchReg,
+ TTSInternalRegs::kSubTypeArgumentReg);
const bool null_is_assignable = Instance::NullIsAssignableTo(type);
// Check bottom types.
diff --git a/sdk/lib/_internal/vm/bin/builtin.dart b/sdk/lib/_internal/vm/bin/builtin.dart
index b5263e0..e39fa7f 100644
--- a/sdk/lib/_internal/vm/bin/builtin.dart
+++ b/sdk/lib/_internal/vm/bin/builtin.dart
@@ -4,7 +4,6 @@
library builtin;
-// NOTE: Do not import 'dart:io' in builtin.
import 'dart:async';
import 'dart:collection' hide LinkedList, LinkedListEntry;
import 'dart:_internal' hide Symbol;
diff --git a/tools/VERSION b/tools/VERSION
index 3c5112c..05b635f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 236
+PRERELEASE 237
PRERELEASE_PATCH 0
\ No newline at end of file