dart-sdk/runtime/vm/raw_object_fields.cc

250 lines
17 KiB
C++
Raw Normal View History

// 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(Field, name_) \
F(Field, owner_) \
F(Field, type_) \
F(Field, guarded_list_length_) \
F(Field, dependent_code_) \
F(Field, initializer_function_) \
F(Field, host_offset_or_field_id_) \
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, loading_unit_) \
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, 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_) \
[vm/compiler] Reland "Further compress the information... in StackMaps." Fixes an assumption that CompressedStackMapsIterator::Find() is never passed a PC offset of 0. Adds back an ASSERT that was dropped which checks for specific cases where a given PC offset does not have a stack map entry. Original commit message: Lifting the PC offset in a2bb730 was a small, lightweight change that gave us big gains, at least on 32-bit architectures. Here, we make much more invasive changes that will improve the amount of memory used by the information previously stored in StackMap objects. Instead of allocating separate objects for StackMaps, we instead compress all StackMap information for a given Code object into a single object (CompressedStackMaps, or CSM for short). This replaces the Array used to store PC offsets (as Smis) and the individual StackMap objects. While we lose all canonicalization for individual StackMap entries, the drop in space required to store stack map information more than offsets that. ----- The impact on AOT snapshot size when compiling the Flutter Gallery in release mode: armv7: Total size -2.58% (Isolate RO: +14.46%, Isolate snapshot: -22.93%) armv8: Total size -1.85% (Isolate RO: +15.69%, Isolate snapshot: -22.97%) The impact on in-memory, not on-disk, size for the Flutter Gallery as seen in the Observatory while running a profile (not release) build: armv7: Drops from 7.1 MB to 6.2MB (-0.9 MB) armv8: Drops from 13.5MB to 11.7MB (-1.8 MB) ----- Bug: https://github.com/dart-lang/sdk/issues/35274, https://github.com/dart-lang/sdk/issues/38873 Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-mac-debug-simdbc64-try Change-Id: I111b129b0ed64f03184370bceb7cda69d5d4b3c9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121700 Commit-Queue: Teagan Strickland <sstrickl@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
2019-10-16 08:25:53 +00:00
F(Code, compressed_stackmaps_) \
F(Code, inlined_id_to_function_) \
F(Code, code_source_map_) \
F(ExceptionHandlers, handled_types_data_) \
F(Context, parent_) \
F(SingleTargetCache, target_) \
F(UnlinkedCall, target_name_) \
F(UnlinkedCall, args_descriptor_) \
Reland "[vm/aot] Only patch call-sites to monomorphic entry-points when the receiver is proven to be a heap object." This reverts commit 5f81efb4a3f7d5ad6a7a6da4e35f572c884abede. Reason for revert: 3xH bot is green again. Original change's description: > Revert "[vm/aot] Only patch call-sites to monomorphic entry-points when the receiver is proven to be a heap object." > > This reverts commit ab2026af45c407eb2958bca3898823d4e6de4dc7. > > Reason for revert: Flutter 3xH is broken on Golem. > > Original change's description: > > [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> > > TBR=kustermann@google.com,rmacnak@google.com,alexmarkov@google.com,sjindel@google.com > > Change-Id: I411aae4b230f2a08146ad3bf3e7a10aa6592db0e > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > 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/+/131660 > Reviewed-by: Samir Jindel <sjindel@google.com> > Commit-Queue: Samir Jindel <sjindel@google.com> TBR=kustermann@google.com,rmacnak@google.com,alexmarkov@google.com,sjindel@google.com # Not skipping CQ checks because original CL landed > 1 day ago. Change-Id: I36e4e9d598033fcc934c2cdf5b061aa11255d3b2 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/+/131837 Reviewed-by: Samir Jindel <sjindel@google.com> Commit-Queue: Samir Jindel <sjindel@google.com>
2020-01-16 14:21:16 +00:00
F(MonomorphicSmiableCall, expected_cid_) \
F(MonomorphicSmiableCall, target_) \
F(CallSiteData, target_name_) \
F(CallSiteData, args_descriptor_) \
F(ICData, entries_) \
F(ICData, owner_) \
F(MegamorphicCache, buckets_) \
F(MegamorphicCache, mask_) \
F(SubtypeTestCache, cache_) \
F(LoadingUnit, parent_) \
F(LoadingUnit, base_objects_) \
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(TypeArguments, nullability_) \
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(PointerBase, data_) \
F(Pointer, type_arguments_) \
F(DynamicLibrary, handle_) \
F(FfiTrampolineData, signature_type_) \
F(FfiTrampolineData, c_signature_) \
F(FfiTrampolineData, callback_target_) \
F(FfiTrampolineData, callback_exceptional_return_) \
F(TypedDataBase, length_) \
F(TypedDataView, typed_data_) \
F(TypedDataView, offset_in_bytes_) \
F(FutureOr, type_arguments_)
[vm/aot] Drop some Function objects not needed at runtime. In particular, don't serialize a function if its code is used by the dispatch table, but there's no need for the function object itself at runtime like dynamic lookup or dynamic invocation forwarders. However, just because the owning function is not needed at runtime, it may be used during serialization for things like assembly label creation. Thus, instead of just clearing out the Code's owner field, we add a new WeakSerializationReference (WSR) object whose target is the original contents of the owner field. The WSR allows the serializer to access the original owner, but also signals to the serializer that the target should not be serialized in AOT snapshots unless there are additional strong (non-WSR) references. If no strong references are found, then the references to the WSR in the snapshot are replaced with a reference to a WSR that only contains the class ID of the original target. The serializer creates only one WSR per class ID. If strong references are found, then the target is still serialized. In this case, the WSR is dropped entirely and any reference to it is replaced with a direct reference to the serialized target. Thus, WSRs only exist in the precompiled runtime for targets with no strong references. Changes on the Flutter gallery in release mode: arm7: total size -1.10%, isolate size -6.08% arm8: total size -1.16%, isolate size -6.09% Bug: https://github.com/dart-lang/sdk/issues/41052 Change-Id: I5b435ca71ef85f50fe3484789087471a91aa4fe2 Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-linux-release-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-precomp-win-release-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/137104 Commit-Queue: Tess Strickland <sstrickl@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com>
2020-03-30 18:33:48 +00:00
#define AOT_CLASSES_AND_FIELDS(F) F(WeakSerializationReference, cid_)
#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, unoptimized_code_) \
F(Field, saved_initial_value_) \
[vm/aot] Drop some Function objects not needed at runtime. In particular, don't serialize a function if its code is used by the dispatch table, but there's no need for the function object itself at runtime like dynamic lookup or dynamic invocation forwarders. However, just because the owning function is not needed at runtime, it may be used during serialization for things like assembly label creation. Thus, instead of just clearing out the Code's owner field, we add a new WeakSerializationReference (WSR) object whose target is the original contents of the owner field. The WSR allows the serializer to access the original owner, but also signals to the serializer that the target should not be serialized in AOT snapshots unless there are additional strong (non-WSR) references. If no strong references are found, then the references to the WSR in the snapshot are replaced with a reference to a WSR that only contains the class ID of the original target. The serializer creates only one WSR per class ID. If strong references are found, then the target is still serialized. In this case, the WSR is dropped entirely and any reference to it is replaced with a direct reference to the serialized target. Thus, WSRs only exist in the precompiled runtime for targets with no strong references. Changes on the Flutter gallery in release mode: arm7: total size -1.10%, isolate size -6.08% arm8: total size -1.16%, isolate size -6.09% Bug: https://github.com/dart-lang/sdk/issues/41052 Change-Id: I5b435ca71ef85f50fe3484789087471a91aa4fe2 Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-linux-release-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-precomp-win-release-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/137104 Commit-Queue: Tess Strickland <sstrickl@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com>
2020-03-30 18:33:48 +00:00
F(Field, type_test_cache_) \
F(WeakSerializationReference, target_)
#define NON_PRODUCT_CLASSES_AND_FIELDS(F) \
F(ReceivePort, debug_name_) \
F(ReceivePort, allocation_location_)
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(class_name##Layout, field_name)},
// clang-format off
OffsetsTable::OffsetsTableEntry OffsetsTable::offsets_table[] = {
COMMON_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
#if !defined(PRODUCT)
NON_PRODUCT_CLASSES_AND_FIELDS(DEFINE_OFFSETS_TABLE_ENTRY)
#endif
#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