ab2026af45
Flutter Gallery ARMv8: -0.8% total, -1.3% instructions Flutter Gallery ARMv7: -0.7% total, -1.2% instructions There are some performance regressions, in four categories: 1. Arithmetic on num types (e.g. MinLib, MaxLib): We believe arithmetic on num types is rare in practice, and can be optimized later by specializing the call-sites. 2. Lack of types (e.g. MeshDecompression, ImagingGaussianBlur, Crypto*): These (and similar benchmarks) are written in a very untyped style, which is not representative of Dart 2 style. We've confirmed that the regressions disappear if the benchmarks are annotated with appropriate types. 3. Megamorphic calls which are specialized in the benchmark (e.g. DeltaBlue): DeltaBlue uses string interpolation in one place, so the toString() method in the string interpolation helper is monomorphic for _Smis. However, in a realistic programs, string interpolation is used much more frequently and with different types, so it's very unlikely that this call would be monomorphic. When string interpolation is removed, there's a remaining 1.3% regression on DeltaBlue which is not yet accounted for. 4. Noisy benchmarks The remaining regressions are on benchmarks which show frequent jitter historically. There are also 1-4% improvements on many benchmarks (Golem's "noise" analysis is hiding many of them, look at the graphs). For the reasons above, we believe the regressions justified by the code size improvement. Change-Id: Ic9b281d4383a6111de9d6f44347976ffa61a6ca6 Cq-Include-Trybots:luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-bare-linux-release-simarm64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/128667 Commit-Queue: Samir Jindel <sjindel@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
252 lines
18 KiB
C++
252 lines
18 KiB
C++
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#include "vm/raw_object_fields.h"
|
|
|
|
namespace dart {
|
|
|
|
#if defined(DART_PRECOMPILER) || !defined(DART_PRODUCT)
|
|
|
|
#define COMMON_CLASSES_AND_FIELDS(F) \
|
|
F(Class, name_) \
|
|
F(Class, user_name_) \
|
|
F(Class, functions_) \
|
|
F(Class, functions_hash_table_) \
|
|
F(Class, fields_) \
|
|
F(Class, offset_in_words_to_field_) \
|
|
F(Class, interfaces_) \
|
|
F(Class, script_) \
|
|
F(Class, library_) \
|
|
F(Class, type_parameters_) \
|
|
F(Class, super_type_) \
|
|
F(Class, signature_function_) \
|
|
F(Class, constants_) \
|
|
F(Class, declaration_type_) \
|
|
F(Class, invocation_dispatcher_cache_) \
|
|
F(Class, allocation_stub_) \
|
|
F(Class, direct_implementors_) \
|
|
F(Class, direct_subclasses_) \
|
|
F(Class, dependent_code_) \
|
|
F(PatchClass, patched_class_) \
|
|
F(PatchClass, origin_class_) \
|
|
F(PatchClass, script_) \
|
|
F(PatchClass, library_kernel_data_) \
|
|
F(Function, name_) \
|
|
F(Function, owner_) \
|
|
F(Function, result_type_) \
|
|
F(Function, parameter_types_) \
|
|
F(Function, parameter_names_) \
|
|
F(Function, type_parameters_) \
|
|
F(Function, data_) \
|
|
F(Function, ic_data_array_) \
|
|
F(Function, code_) \
|
|
F(ClosureData, context_scope_) \
|
|
F(ClosureData, parent_function_) \
|
|
F(ClosureData, signature_type_) \
|
|
F(ClosureData, closure_) \
|
|
F(SignatureData, parent_function_) \
|
|
F(SignatureData, signature_type_) \
|
|
F(RedirectionData, type_) \
|
|
F(RedirectionData, identifier_) \
|
|
F(RedirectionData, target_) \
|
|
F(Field, name_) \
|
|
F(Field, owner_) \
|
|
F(Field, type_) \
|
|
F(Field, guarded_list_length_) \
|
|
F(Field, dependent_code_) \
|
|
F(Field, initializer_function_) \
|
|
F(Script, url_) \
|
|
F(Script, resolved_url_) \
|
|
F(Script, compile_time_constants_) \
|
|
F(Script, line_starts_) \
|
|
F(Script, debug_positions_) \
|
|
F(Script, kernel_program_info_) \
|
|
F(Script, source_) \
|
|
F(Library, name_) \
|
|
F(Library, url_) \
|
|
F(Library, private_key_) \
|
|
F(Library, dictionary_) \
|
|
F(Library, metadata_) \
|
|
F(Library, toplevel_class_) \
|
|
F(Library, used_scripts_) \
|
|
F(Library, imports_) \
|
|
F(Library, exports_) \
|
|
F(Library, kernel_data_) \
|
|
F(Library, resolved_names_) \
|
|
F(Library, exported_names_) \
|
|
F(Library, loaded_scripts_) \
|
|
F(Namespace, library_) \
|
|
F(Namespace, show_names_) \
|
|
F(Namespace, hide_names_) \
|
|
F(Namespace, metadata_field_) \
|
|
F(KernelProgramInfo, string_offsets_) \
|
|
F(KernelProgramInfo, string_data_) \
|
|
F(KernelProgramInfo, canonical_names_) \
|
|
F(KernelProgramInfo, metadata_payloads_) \
|
|
F(KernelProgramInfo, metadata_mappings_) \
|
|
F(KernelProgramInfo, scripts_) \
|
|
F(KernelProgramInfo, constants_) \
|
|
F(KernelProgramInfo, bytecode_component_) \
|
|
F(KernelProgramInfo, potential_natives_) \
|
|
F(KernelProgramInfo, potential_pragma_functions_) \
|
|
F(KernelProgramInfo, constants_table_) \
|
|
F(KernelProgramInfo, libraries_cache_) \
|
|
F(KernelProgramInfo, classes_cache_) \
|
|
F(KernelProgramInfo, retained_kernel_blob_) \
|
|
F(Code, object_pool_) \
|
|
F(Code, instructions_) \
|
|
F(Code, owner_) \
|
|
F(Code, exception_handlers_) \
|
|
F(Code, pc_descriptors_) \
|
|
F(Code, catch_entry_) \
|
|
F(Code, compressed_stackmaps_) \
|
|
F(Code, inlined_id_to_function_) \
|
|
F(Code, code_source_map_) \
|
|
F(Bytecode, object_pool_) \
|
|
F(Bytecode, instructions_) \
|
|
F(Bytecode, function_) \
|
|
F(Bytecode, exception_handlers_) \
|
|
F(Bytecode, pc_descriptors_) \
|
|
F(Bytecode, closures_) \
|
|
F(ExceptionHandlers, handled_types_data_) \
|
|
F(Context, parent_) \
|
|
F(ParameterTypeCheck, param_) \
|
|
F(ParameterTypeCheck, type_or_bound_) \
|
|
F(ParameterTypeCheck, name_) \
|
|
F(ParameterTypeCheck, cache_) \
|
|
F(SingleTargetCache, target_) \
|
|
F(UnlinkedCall, target_name_) \
|
|
F(UnlinkedCall, args_descriptor_) \
|
|
F(MonomorphicSmiableCall, expected_cid_) \
|
|
F(MonomorphicSmiableCall, target_) \
|
|
F(ICData, entries_) \
|
|
F(ICData, target_name_) \
|
|
F(ICData, args_descriptor_) \
|
|
F(ICData, owner_) \
|
|
F(MegamorphicCache, buckets_) \
|
|
F(MegamorphicCache, mask_) \
|
|
F(MegamorphicCache, target_name_) \
|
|
F(MegamorphicCache, args_descriptor_) \
|
|
F(SubtypeTestCache, cache_) \
|
|
F(ApiError, message_) \
|
|
F(LanguageError, previous_error_) \
|
|
F(LanguageError, script_) \
|
|
F(LanguageError, message_) \
|
|
F(LanguageError, formatted_message_) \
|
|
F(UnhandledException, exception_) \
|
|
F(UnhandledException, stacktrace_) \
|
|
F(UnwindError, message_) \
|
|
F(LibraryPrefix, name_) \
|
|
F(LibraryPrefix, importer_) \
|
|
F(LibraryPrefix, imports_) \
|
|
F(TypeArguments, instantiations_) \
|
|
F(TypeArguments, length_) \
|
|
F(TypeArguments, hash_) \
|
|
F(AbstractType, type_test_stub_) \
|
|
F(Type, type_test_stub_) \
|
|
F(Type, type_class_id_) \
|
|
F(Type, arguments_) \
|
|
F(Type, hash_) \
|
|
F(Type, signature_) \
|
|
F(TypeRef, type_test_stub_) \
|
|
F(TypeRef, type_) \
|
|
F(TypeParameter, type_test_stub_) \
|
|
F(TypeParameter, name_) \
|
|
F(TypeParameter, hash_) \
|
|
F(TypeParameter, bound_) \
|
|
F(TypeParameter, parameterized_function_) \
|
|
F(Closure, instantiator_type_arguments_) \
|
|
F(Closure, function_type_arguments_) \
|
|
F(Closure, delayed_type_arguments_) \
|
|
F(Closure, function_) \
|
|
F(Closure, context_) \
|
|
F(Closure, hash_) \
|
|
F(String, length_) \
|
|
F(String, hash_) \
|
|
F(Array, type_arguments_) \
|
|
F(Array, length_) \
|
|
F(GrowableObjectArray, type_arguments_) \
|
|
F(GrowableObjectArray, length_) \
|
|
F(GrowableObjectArray, data_) \
|
|
F(LinkedHashMap, type_arguments_) \
|
|
F(LinkedHashMap, index_) \
|
|
F(LinkedHashMap, hash_mask_) \
|
|
F(LinkedHashMap, data_) \
|
|
F(LinkedHashMap, used_data_) \
|
|
F(LinkedHashMap, deleted_keys_) \
|
|
F(TypedData, length_) \
|
|
F(ExternalTypedData, length_) \
|
|
F(ReceivePort, send_port_) \
|
|
F(ReceivePort, handler_) \
|
|
F(StackTrace, async_link_) \
|
|
F(StackTrace, code_array_) \
|
|
F(StackTrace, pc_offset_array_) \
|
|
F(RegExp, num_bracket_expressions_) \
|
|
F(RegExp, capture_name_map_) \
|
|
F(RegExp, pattern_) \
|
|
F(RegExp, external_one_byte_function_) \
|
|
F(RegExp, external_two_byte_function_) \
|
|
F(RegExp, external_one_byte_sticky_function_) \
|
|
F(RegExp, external_two_byte_sticky_function_) \
|
|
F(WeakProperty, key_) \
|
|
F(WeakProperty, value_) \
|
|
F(MirrorReference, referent_) \
|
|
F(UserTag, label_) \
|
|
F(Pointer, type_arguments_) \
|
|
F(Pointer, c_memory_address_) \
|
|
F(DynamicLibrary, handle_) \
|
|
F(FfiTrampolineData, signature_type_) \
|
|
F(FfiTrampolineData, c_signature_) \
|
|
F(FfiTrampolineData, callback_target_) \
|
|
F(FfiTrampolineData, callback_exceptional_return_) \
|
|
F(TypedDataBase, data_) \
|
|
F(TypedDataBase, length_) \
|
|
F(TypedDataView, typed_data_) \
|
|
F(TypedDataView, offset_in_bytes_)
|
|
|
|
#define AOT_CLASSES_AND_FIELDS(F)
|
|
|
|
#define JIT_CLASSES_AND_FIELDS(F) \
|
|
F(Code, active_instructions_) \
|
|
F(Code, deopt_info_array_) \
|
|
F(Code, static_calls_target_table_) \
|
|
F(ICData, receivers_static_type_) \
|
|
F(Function, bytecode_) \
|
|
F(Function, unoptimized_code_) \
|
|
F(Field, saved_initial_value_) \
|
|
F(Field, type_test_cache_)
|
|
|
|
OffsetsTable::OffsetsTable(Zone* zone) : cached_offsets_(zone) {
|
|
for (intptr_t i = 0; offsets_table[i].class_id != -1; ++i) {
|
|
OffsetsTableEntry entry = offsets_table[i];
|
|
cached_offsets_.Insert({{entry.class_id, entry.offset}, entry.field_name});
|
|
}
|
|
}
|
|
|
|
const char* OffsetsTable::FieldNameForOffset(intptr_t class_id,
|
|
intptr_t offset) {
|
|
return cached_offsets_.LookupValue({class_id, offset});
|
|
}
|
|
|
|
#define DEFINE_OFFSETS_TABLE_ENTRY(class_name, field_name) \
|
|
{class_name::kClassId, #field_name, OFFSET_OF(Raw##class_name, field_name)},
|
|
|
|
// clang-format off
|
|
OffsetsTable::OffsetsTableEntry OffsetsTable::offsets_table[] = {
|
|
COMMON_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
|
|
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
AOT_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
|
|
#else
|
|
JIT_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
|
|
#endif
|
|
{-1, nullptr, -1}
|
|
};
|
|
// clang-format on
|
|
|
|
#undef DEFINE_OFFSETS_TABLE_ENTRY
|
|
|
|
#endif
|
|
|
|
} // namespace dart
|