Files
sdk/runtime/vm/raw_object_fields.cc
T
Samir Jindel ab2026af45 [vm/aot] Only patch call-sites to monomorphic entry-points when the receiver is proven to be a heap object.
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>
2020-01-14 13:18:05 +00:00

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