1// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_COMPILER_AOT_DISPATCH_TABLE_GENERATOR_H_
6#define RUNTIME_VM_COMPILER_AOT_DISPATCH_TABLE_GENERATOR_H_
7
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
10#endif // defined(DART_PRECOMPILED_RUNTIME)
11
12#include "vm/compiler/frontend/kernel_translation_helper.h"
13#include "vm/object.h"
14
15namespace dart {
16
17class ClassTable;
18class Precompiler;
19class PrecompilerTracer;
20
21namespace compiler {
22
23class SelectorRow;
24
25struct TableSelector {
26 TableSelector(int32_t _id,
27 int32_t _call_count,
28 int32_t _offset,
29 bool _called_on_null,
30 bool _torn_off)
31 : id(_id),
32 call_count(_call_count),
33 offset(_offset),
34 called_on_null(_called_on_null),
35 torn_off(_torn_off) {}
36
37 bool IsUsed() const { return call_count > 0; }
38
39 // ID assigned to the selector.
40 int32_t id;
41 // Number of dispatch table call sites with this selector (conservative:
42 // number may be bigger, but not smaller, than actual number of call sites).
43 int32_t call_count;
44 // Table offset assigned to the selector by the dispatch table generator.
45 int32_t offset;
46 // Are there any call sites with this selector where the receiver may be null?
47 bool called_on_null;
48 // Is this method ever torn off, i.e. is its method extractor accessed?
49 bool torn_off;
50 // Is the selector part of the interface on Null (same as Object)?
51 bool on_null_interface = false;
52 // Do any targets of this selector assume that an args descriptor is passed?
53 bool requires_args_descriptor = false;
54};
55
56class SelectorMap {
57 public:
58 explicit SelectorMap(Zone* zone) : zone_(zone) {}
59
60 // Get the selector for this interface target, or null if the function does
61 // not have a selector assigned.
62 const TableSelector* GetSelector(const Function& interface_target) const;
63
64 private:
65 static const int32_t kInvalidSelectorId =
66 kernel::ProcedureAttributesMetadata::kInvalidSelectorId;
67 static const int32_t kInvalidSelectorOffset = -1;
68
69 int32_t SelectorId(const Function& interface_target) const;
70
71 void AddSelector(int32_t call_count, bool called_on_null, bool torn_off);
72 void SetSelectorProperties(int32_t sid,
73 bool on_null_interface,
74 bool requires_args_descriptor);
75
76 int32_t NumIds() const { return selectors_.length(); }
77
78 friend class dart::Precompiler;
79 friend class dart::PrecompilerTracer;
80 friend class DispatchTableGenerator;
81 friend class SelectorRow;
82
83 Zone* zone_;
84 GrowableArray<TableSelector> selectors_;
85};
86
87class DispatchTableGenerator {
88 public:
89 explicit DispatchTableGenerator(Zone* zone);
90
91 SelectorMap* selector_map() { return &selector_map_; }
92
93 // Find suitable selectors and compute offsets for them.
94 void Initialize(ClassTable* table);
95
96 // Build up an array of Code objects, used to serialize the information
97 // deserialized as a DispatchTable at runtime.
98 ArrayPtr BuildCodeArray();
99
100 private:
101 void ReadTableSelectorInfo();
102 void NumberSelectors();
103 void SetupSelectorRows();
104 void ComputeSelectorOffsets();
105
106 Zone* const zone_;
107 ClassTable* classes_;
108 int32_t num_selectors_;
109 int32_t num_classes_;
110 int32_t table_size_;
111
112 GrowableArray<SelectorRow*> table_rows_;
113
114 SelectorMap selector_map_;
115};
116
117} // namespace compiler
118} // namespace dart
119
120#endif // RUNTIME_VM_COMPILER_AOT_DISPATCH_TABLE_GENERATOR_H_
121