mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:19:47 +00:00
[vm] Exclude class name from function name in instruction sizes json.
Issue https://github.com/dart-lang/sdk/issues/41249 Cq-Include-Trybots: luci.dart.try:pkg-linux-debug-try,pkg-linux-release-try,pkg-win-release-try,pkg-mac-release-try Change-Id: Idf2bb9c9d6392c7a95aa09a2cc1f2190adcf782d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150522 Commit-Queue: Vyacheslav Egorov <vegorov@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
f40875bf1b
commit
45310394a6
|
@ -97,11 +97,12 @@ void main(List<String> args) {
|
|||
reason: 'Sizes file is non-empty');
|
||||
|
||||
// Check for duplicated symbols (using both raw and scrubbed names).
|
||||
final symbolRawNamesByLibrary = Map<String, Set<String>>();
|
||||
final symbolScrubbedNamesByLibrary = Map<String, Set<String>>();
|
||||
// Maps below contain mappings library-uri -> class-name -> names.
|
||||
final symbolRawNames = <String, Map<String, Set<String>>>{};
|
||||
final symbolScrubbedNames = <String, Map<String, Set<String>>>{};
|
||||
|
||||
Set<String> getSetOfNames(
|
||||
Map<String, Set<String>> map, String libraryUri) {
|
||||
Set<String> getSetOfNames(Map<String, Map<String, Set<String>>> map,
|
||||
String libraryUri, String className) {
|
||||
// For file uris make sure to canonicalize the path. This prevents
|
||||
// issues with mismatching case on Windows which has case insensitive
|
||||
// file system.
|
||||
|
@ -112,48 +113,60 @@ void main(List<String> args) {
|
|||
Uri.file(path.canonicalize(uri.toFilePath())).toString();
|
||||
}
|
||||
}
|
||||
return map.putIfAbsent(libraryUri ?? '', () => {});
|
||||
return map
|
||||
.putIfAbsent(libraryUri ?? '', () => {})
|
||||
.putIfAbsent(className ?? '', () => {});
|
||||
}
|
||||
|
||||
for (var sym in symbols) {
|
||||
expect(
|
||||
getSetOfNames(symbolRawNamesByLibrary, sym.libraryUri)
|
||||
getSetOfNames(symbolRawNames, sym.libraryUri, sym.className)
|
||||
.add(sym.name.raw),
|
||||
isTrue,
|
||||
reason:
|
||||
'All symbols should have unique names (within libraries): ${sym.name.raw}');
|
||||
expect(
|
||||
getSetOfNames(symbolScrubbedNamesByLibrary, sym.libraryUri)
|
||||
getSetOfNames(symbolScrubbedNames, sym.libraryUri, sym.className)
|
||||
.add(sym.name.scrubbed),
|
||||
isTrue,
|
||||
reason: 'Scrubbing the name should not make it non-unique');
|
||||
}
|
||||
|
||||
// Check for expected names which should appear in the output.
|
||||
final inputDartSymbolNames = symbolScrubbedNamesByLibrary[
|
||||
final inputDartSymbolNames = symbolScrubbedNames[
|
||||
Uri.file(path.canonicalize(inputDart)).toString()];
|
||||
expect(inputDartSymbolNames, isNotNull,
|
||||
reason: 'Symbols from input.dart are included into sizes output');
|
||||
|
||||
expect(inputDartSymbolNames, contains('makeSomeClosures'));
|
||||
final closures = inputDartSymbolNames.where(
|
||||
expect(inputDartSymbolNames[''], isNotNull,
|
||||
reason: 'Should include top-level members from input.dart');
|
||||
expect(inputDartSymbolNames[''], contains('makeSomeClosures'));
|
||||
final closures = inputDartSymbolNames[''].where(
|
||||
(name) => name.startsWith('makeSomeClosures.<anonymous closure'));
|
||||
expect(closures.length, 3);
|
||||
expect(inputDartSymbolNames, contains('A.tornOff'));
|
||||
expect(inputDartSymbolNames, contains('[tear-off] A.tornOff'));
|
||||
expect(inputDartSymbolNames,
|
||||
contains('[tear-off-extractor] A.get:tornOff'));
|
||||
expect(inputDartSymbolNames, contains('B.tornOff'));
|
||||
expect(inputDartSymbolNames, contains('[tear-off] B.tornOff'));
|
||||
expect(inputDartSymbolNames,
|
||||
contains('[tear-off-extractor] B.get:tornOff'));
|
||||
expect(closures.length, 3,
|
||||
reason: 'There are three closures inside makeSomeClosure');
|
||||
|
||||
expect(inputDartSymbolNames['A'], isNotNull,
|
||||
reason: 'Should include class A members from input.dart');
|
||||
expect(inputDartSymbolNames['A'], contains('tornOff'));
|
||||
expect(inputDartSymbolNames['A'], contains('[tear-off] tornOff'));
|
||||
expect(inputDartSymbolNames['A'],
|
||||
contains('[tear-off-extractor] get:tornOff'));
|
||||
|
||||
expect(inputDartSymbolNames['B'], isNotNull,
|
||||
reason: 'Should include class B members from input.dart');
|
||||
expect(inputDartSymbolNames['B'], contains('tornOff'));
|
||||
expect(inputDartSymbolNames['B'], contains('[tear-off] tornOff'));
|
||||
expect(inputDartSymbolNames['B'],
|
||||
contains('[tear-off-extractor] get:tornOff'));
|
||||
|
||||
// Presence of async modifier should not cause tear-off name to end
|
||||
// with {body}.
|
||||
expect(inputDartSymbolNames, contains('[tear-off] C.tornOff'));
|
||||
expect(inputDartSymbolNames['C'], contains('[tear-off] tornOff'));
|
||||
|
||||
// Check that output does not contain '[unknown stub]'
|
||||
expect(symbolRawNamesByLibrary[''], isNot(contains('[unknown stub]')));
|
||||
expect(symbolRawNames[''][''], isNot(contains('[unknown stub]')),
|
||||
reason: 'All stubs must be named');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -417,10 +417,11 @@ void Disassembler::DisassembleCodeHelper(const char* function_fullname,
|
|||
} else if (function.IsNull()) {
|
||||
cls ^= code.owner();
|
||||
if (cls.IsNull()) {
|
||||
THR_Print(" 0x%" Px ": %s, (%s)%s\n", base + offset,
|
||||
code.QualifiedName(Object::kScrubbedName,
|
||||
Object::NameDisambiguation::kYes),
|
||||
skind, s_entry_point);
|
||||
THR_Print(
|
||||
" 0x%" Px ": %s, (%s)%s\n", base + offset,
|
||||
code.QualifiedName(NameFormattingParams(
|
||||
Object::kScrubbedName, Object::NameDisambiguation::kYes)),
|
||||
skind, s_entry_point);
|
||||
} else {
|
||||
THR_Print(" 0x%" Px ": allocation stub for %s, (%s)%s\n",
|
||||
base + offset, cls.ToCString(), skind, s_entry_point);
|
||||
|
|
|
@ -337,9 +337,10 @@ void ImageWriter::DumpInstructionsSizes() {
|
|||
js.PrintPropertyStr("l", url);
|
||||
js.PrintPropertyStr("c", name);
|
||||
}
|
||||
js.PrintProperty(
|
||||
"n", data.code_->QualifiedName(Object::kInternalName,
|
||||
Object::NameDisambiguation::kYes));
|
||||
js.PrintProperty("n",
|
||||
data.code_->QualifiedName(
|
||||
NameFormattingParams::DisambiguatedWithoutClassName(
|
||||
Object::kInternalName)));
|
||||
js.PrintProperty("s", SizeInSnapshot(data.insns_->raw()));
|
||||
js.CloseObject();
|
||||
}
|
||||
|
|
|
@ -8839,27 +8839,24 @@ StringPtr Function::UserVisibleName() const {
|
|||
StringPtr Function::QualifiedScrubbedName() const {
|
||||
Thread* thread = Thread::Current();
|
||||
ZoneTextBuffer printer(thread->zone());
|
||||
PrintQualifiedName(kScrubbedName, &printer);
|
||||
PrintQualifiedName(NameFormattingParams(kScrubbedName), &printer);
|
||||
return Symbols::New(thread, printer.buffer());
|
||||
}
|
||||
|
||||
StringPtr Function::QualifiedUserVisibleName() const {
|
||||
Thread* thread = Thread::Current();
|
||||
ZoneTextBuffer printer(thread->zone());
|
||||
PrintQualifiedName(kUserVisibleName, &printer);
|
||||
PrintQualifiedName(NameFormattingParams(kUserVisibleName), &printer);
|
||||
return Symbols::New(thread, printer.buffer());
|
||||
}
|
||||
|
||||
void Function::PrintQualifiedName(
|
||||
NameVisibility name_visibility,
|
||||
ZoneTextBuffer* printer,
|
||||
NameDisambiguation name_disambiguation /* = NameDisambiguation::kNo */)
|
||||
const {
|
||||
void Function::PrintQualifiedName(const NameFormattingParams& params,
|
||||
ZoneTextBuffer* printer) const {
|
||||
// If |this| is the generated asynchronous body closure, use the
|
||||
// name of the parent function.
|
||||
Function& fun = Function::Handle(raw());
|
||||
|
||||
if (name_disambiguation == NameDisambiguation::kYes) {
|
||||
if (params.disambiguate_names) {
|
||||
if (fun.IsInvokeFieldDispatcher()) {
|
||||
printer->AddString("[invoke-field] ");
|
||||
}
|
||||
|
@ -8891,50 +8888,49 @@ void Function::PrintQualifiedName(
|
|||
// the parent.
|
||||
parent = parent.parent_function();
|
||||
}
|
||||
parent.PrintQualifiedName(name_visibility, printer, name_disambiguation);
|
||||
parent.PrintQualifiedName(params, printer);
|
||||
// A function's scrubbed name and its user visible name are identical.
|
||||
printer->AddString(".");
|
||||
if (name_disambiguation == NameDisambiguation::kYes &&
|
||||
if (params.disambiguate_names &&
|
||||
fun.name() == Symbols::AnonymousClosure().raw()) {
|
||||
printer->Printf("<anonymous closure @%" Pd ">", fun.token_pos().Pos());
|
||||
} else {
|
||||
printer->AddString(fun.NameCString(name_visibility));
|
||||
printer->AddString(fun.NameCString(params.name_visibility));
|
||||
}
|
||||
// If we skipped rewritten async/async*/sync* body then append a suffix
|
||||
// to the end of the name.
|
||||
if (fun.raw() != raw() &&
|
||||
name_disambiguation == NameDisambiguation::kYes) {
|
||||
if (fun.raw() != raw() && params.disambiguate_names) {
|
||||
printer->AddString("{body}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
const Class& cls = Class::Handle(Owner());
|
||||
if (!cls.IsTopLevel()) {
|
||||
if (fun.kind() == FunctionLayout::kConstructor) {
|
||||
printer->AddString("new ");
|
||||
} else {
|
||||
|
||||
if (fun.kind() == FunctionLayout::kConstructor) {
|
||||
printer->AddString("new ");
|
||||
} else if (params.include_class_name) {
|
||||
const Class& cls = Class::Handle(Owner());
|
||||
if (!cls.IsTopLevel()) {
|
||||
const Class& mixin = Class::Handle(cls.Mixin());
|
||||
printer->AddString(name_visibility == kUserVisibleName
|
||||
printer->AddString(params.name_visibility == kUserVisibleName
|
||||
? mixin.UserVisibleNameCString()
|
||||
: cls.NameCString(name_visibility));
|
||||
: cls.NameCString(params.name_visibility));
|
||||
printer->AddString(".");
|
||||
}
|
||||
}
|
||||
|
||||
printer->AddString(fun.NameCString(name_visibility));
|
||||
printer->AddString(fun.NameCString(params.name_visibility));
|
||||
|
||||
// If we skipped rewritten async/async*/sync* body then append a suffix
|
||||
// to the end of the name.
|
||||
if (fun.raw() != raw() && name_disambiguation == NameDisambiguation::kYes) {
|
||||
if (fun.raw() != raw() && params.disambiguate_names) {
|
||||
printer->AddString("{body}");
|
||||
}
|
||||
|
||||
// Field dispatchers are specialized for an argument descriptor so there
|
||||
// might be multiples of them with the same name but different argument
|
||||
// descriptors. Add a suffix to disambiguate.
|
||||
if (name_disambiguation == NameDisambiguation::kYes &&
|
||||
fun.IsInvokeFieldDispatcher()) {
|
||||
if (params.disambiguate_names && fun.IsInvokeFieldDispatcher()) {
|
||||
printer->AddString(" ");
|
||||
if (NumTypeParameters() != 0) {
|
||||
printer->Printf("<%" Pd ">", fun.NumTypeParameters());
|
||||
|
@ -16229,7 +16225,8 @@ intptr_t Code::GetDeoptIdForOsr(uword pc) const {
|
|||
|
||||
const char* Code::ToCString() const {
|
||||
return OS::SCreate(Thread::Current()->zone(), "Code(%s)",
|
||||
QualifiedName(kScrubbedName, NameDisambiguation::kYes));
|
||||
QualifiedName(NameFormattingParams(
|
||||
kScrubbedName, NameDisambiguation::kYes)));
|
||||
}
|
||||
|
||||
const char* Code::Name() const {
|
||||
|
@ -16266,16 +16263,14 @@ const char* Code::Name() const {
|
|||
}
|
||||
}
|
||||
|
||||
const char* Code::QualifiedName(NameVisibility name_visibility,
|
||||
NameDisambiguation name_disambiguation) const {
|
||||
const char* Code::QualifiedName(const NameFormattingParams& params) const {
|
||||
Zone* zone = Thread::Current()->zone();
|
||||
const Object& obj =
|
||||
Object::Handle(zone, WeakSerializationReference::UnwrapIfTarget(owner()));
|
||||
if (obj.IsFunction()) {
|
||||
ZoneTextBuffer printer(zone);
|
||||
printer.AddString(is_optimized() ? "[Optimized] " : "[Unoptimized] ");
|
||||
Function::Cast(obj).PrintQualifiedName(name_visibility, &printer,
|
||||
name_disambiguation);
|
||||
Function::Cast(obj).PrintQualifiedName(params, &printer);
|
||||
return printer.buffer();
|
||||
}
|
||||
return Name();
|
||||
|
@ -18745,7 +18740,9 @@ void AbstractType::PrintName(
|
|||
} else if (param.parameterized_function() != Function::null()) {
|
||||
const Function& func =
|
||||
Function::Handle(zone, param.parameterized_function());
|
||||
func.PrintQualifiedName(name_visibility, printer, name_disambiguation);
|
||||
func.PrintQualifiedName(
|
||||
NameFormattingParams(name_visibility, name_disambiguation),
|
||||
printer);
|
||||
printer->AddString("::");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2427,6 +2427,32 @@ enum {
|
|||
kAllFree = kMaxInt32,
|
||||
};
|
||||
|
||||
// Formatting configuration for Function::PrintQualifiedName.
|
||||
struct NameFormattingParams {
|
||||
Object::NameVisibility name_visibility;
|
||||
bool disambiguate_names;
|
||||
|
||||
// By default function name includes the name of the enclosing class if any.
|
||||
// However in some context this information is redundant and class name
|
||||
// is already known. In this case setting |include_class_name| to false
|
||||
// allows you to exclude this information from the formatted name.
|
||||
bool include_class_name = true;
|
||||
|
||||
NameFormattingParams(Object::NameVisibility visibility,
|
||||
Object::NameDisambiguation name_disambiguation =
|
||||
Object::NameDisambiguation::kNo)
|
||||
: name_visibility(visibility),
|
||||
disambiguate_names(name_disambiguation ==
|
||||
Object::NameDisambiguation::kYes) {}
|
||||
|
||||
static NameFormattingParams DisambiguatedWithoutClassName(
|
||||
Object::NameVisibility visibility) {
|
||||
NameFormattingParams params(visibility, Object::NameDisambiguation::kYes);
|
||||
params.include_class_name = false;
|
||||
return params;
|
||||
}
|
||||
};
|
||||
|
||||
class Function : public Object {
|
||||
public:
|
||||
StringPtr name() const { return raw_ptr()->name_; }
|
||||
|
@ -2435,10 +2461,8 @@ class Function : public Object {
|
|||
|
||||
const char* NameCString(NameVisibility name_visibility) const;
|
||||
|
||||
void PrintQualifiedName(
|
||||
NameVisibility name_visibility,
|
||||
ZoneTextBuffer* printer,
|
||||
NameDisambiguation name_disambiguation = NameDisambiguation::kNo) const;
|
||||
void PrintQualifiedName(const NameFormattingParams& params,
|
||||
ZoneTextBuffer* printer) const;
|
||||
StringPtr QualifiedScrubbedName() const;
|
||||
StringPtr QualifiedUserVisibleName() const;
|
||||
|
||||
|
@ -6339,8 +6363,7 @@ class Code : public Object {
|
|||
intptr_t GetDeoptIdForOsr(uword pc) const;
|
||||
|
||||
const char* Name() const;
|
||||
const char* QualifiedName(NameVisibility name_visibility,
|
||||
NameDisambiguation name_disambiguation) const;
|
||||
const char* QualifiedName(const NameFormattingParams& params) const;
|
||||
|
||||
int64_t compile_timestamp() const {
|
||||
#if defined(PRODUCT)
|
||||
|
|
|
@ -876,8 +876,8 @@ void Code::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
|||
AddCommonObjectProperties(&jsobj, "Code", ref);
|
||||
jsobj.AddFixedServiceId("code/%" Px64 "-%" Px "", compile_timestamp(),
|
||||
PayloadStart());
|
||||
const char* qualified_name =
|
||||
QualifiedName(kUserVisibleName, NameDisambiguation::kNo);
|
||||
const char* qualified_name = QualifiedName(
|
||||
NameFormattingParams(kUserVisibleName, NameDisambiguation::kNo));
|
||||
const char* vm_name = Name();
|
||||
AddNameProperties(&jsobj, qualified_name, vm_name);
|
||||
const bool is_stub =
|
||||
|
|
|
@ -499,8 +499,8 @@ class AbstractCode {
|
|||
|
||||
const char* QualifiedName() const {
|
||||
if (code_.IsCode()) {
|
||||
return Code::Cast(code_).QualifiedName(Object::kUserVisibleName,
|
||||
Object::NameDisambiguation::kNo);
|
||||
return Code::Cast(code_).QualifiedName(
|
||||
NameFormattingParams(Object::kUserVisibleName));
|
||||
} else if (code_.IsBytecode()) {
|
||||
return Bytecode::Cast(code_).QualifiedName();
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue