Skip to content

Commit b32d196

Browse files
aartbikcommit-bot@chromium.org
authored andcommitted
[dart/vm] Replaces eager with lazy reading of constants table
Rationale: Previously all constants were read from the constants table, whether they were needed (at that point or at all) or not. This CL replaces that eager reading with a lazy reading that makes the raw bytes of the constants table available through KernelProgramInfo and attaches a hashmap to KernelProgramInfo, which maps offsets into the constant table to evaluated constants. The maps starts empty and on a miss, the constant is evaluated, but no sooner than when it it needed. #36220 Change-Id: Ief4df3d70c950c4beb61d896632ce06cfd12d525 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99088 Commit-Queue: Aart Bik <[email protected]> Reviewed-by: Alexander Markov <[email protected]>
1 parent 32df04a commit b32d196

12 files changed

Lines changed: 445 additions & 501 deletions

runtime/vm/class_finalizer.cc

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,14 +1197,7 @@ RawError* ClassFinalizer::LoadClassMembers(const Class& cls) {
11971197
kernel::BytecodeReader::LoadClassDeclaration(cls);
11981198
}
11991199
#endif
1200-
// TODO(36584) : We expect is_type_finalized to be true for all classes
1201-
// here, but with eager reading of the constant table we get into
1202-
// situations where we see classes whose types have not been finalized yet,
1203-
// the real solution is to implement lazy evaluation of constants. This is
1204-
// a temporary workaround until lazy evaluation is implemented.
1205-
if (!cls.is_type_finalized()) {
1206-
FinalizeTypesInClass(cls);
1207-
}
1200+
ASSERT(cls.is_type_finalized());
12081201
ClassFinalizer::FinalizeClass(cls);
12091202
return Error::null();
12101203
} else {

runtime/vm/compiler/frontend/constant_evaluator.cc

Lines changed: 246 additions & 283 deletions
Large diffs are not rendered by default.

runtime/vm/compiler/frontend/constant_evaluator.h

Lines changed: 6 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ class ConstantEvaluator {
5656
RawObject* EvaluateExpressionSafe(intptr_t offset);
5757
RawObject* EvaluateAnnotations();
5858

59+
// Evaluates a constant at the given offset (possibly by recursing
60+
// into sub-constants).
61+
RawInstance* EvaluateConstantExpression(intptr_t constant_offset);
62+
5963
private:
64+
RawInstance* EvaluateConstant(intptr_t constant_offset);
65+
6066
void BailoutIfBackgroundCompilation();
6167

6268
bool IsBuildingFlowGraph() const;
@@ -88,7 +94,6 @@ class ConstantEvaluator {
8894
void EvaluateDoubleLiteral();
8995
void EvaluateBoolLiteral(bool value);
9096
void EvaluateNullLiteral();
91-
void EvaluateConstantExpression(Tag tag);
9297

9398
void EvaluateGetStringLength(intptr_t expression_offset,
9499
TokenPosition position);
@@ -140,59 +145,6 @@ class ConstantEvaluator {
140145
DISALLOW_COPY_AND_ASSIGN(ConstantEvaluator);
141146
};
142147

143-
// Helper class that reads a kernel Constant from binary.
144-
class ConstantHelper {
145-
public:
146-
ConstantHelper(Zone* zone,
147-
KernelReaderHelper* helper,
148-
TypeTranslator* type_translator,
149-
ActiveClass* active_class,
150-
NameIndex skip_vmservice_library);
151-
152-
// Reads the constant table from the binary.
153-
//
154-
// This method assumes the Reader is positioned already at the constant table
155-
// and an active class scope is setup.
156-
const Array& ReadConstantTable();
157-
158-
private:
159-
const Script& script() const { return helper_.script_; }
160-
161-
void InstantiateTypeArguments(const Class& receiver_class,
162-
TypeArguments* type_arguments);
163-
164-
// If [index] has `dart:vm_service` as a parent and we are skipping the VM
165-
// service library, this method returns `true`, otherwise `false`.
166-
bool ShouldSkipConstant(NameIndex index);
167-
168-
Zone* zone_;
169-
KernelReaderHelper& helper_;
170-
TypeTranslator& type_translator_;
171-
ActiveClass* const active_class_;
172-
ConstantEvaluator const_evaluator_;
173-
TranslationHelper& translation_helper_;
174-
NameIndex skip_vmservice_library_;
175-
Class& symbol_class_;
176-
Field& symbol_name_field_;
177-
AbstractType& temp_type_;
178-
TypeArguments& temp_type_arguments_;
179-
TypeArguments& temp_type_arguments2_;
180-
TypeArguments& temp_type_arguments3_;
181-
Object& temp_object_;
182-
String& temp_string_;
183-
Array& temp_array_;
184-
Instance& temp_instance_;
185-
Field& temp_field_;
186-
Class& temp_class_;
187-
Library& temp_library_;
188-
Function& temp_function_;
189-
Closure& temp_closure_;
190-
Context& temp_context_;
191-
Integer& temp_integer_;
192-
193-
DISALLOW_COPY_AND_ASSIGN(ConstantHelper);
194-
};
195-
196148
class KernelConstMapKeyEqualsTraits : public AllStatic {
197149
public:
198150
static const char* Name() { return "KernelConstMapKeyEqualsTraits"; }

runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3776,10 +3776,8 @@ Fragment StreamingFlowGraphBuilder::BuildConstantExpression(
37763776
}
37773777
if (position != nullptr) *position = p;
37783778
const intptr_t constant_offset = ReadUInt();
3779-
KernelConstantsMap constant_map(H.constants().raw());
3780-
Fragment result =
3781-
Constant(Object::ZoneHandle(Z, constant_map.GetOrDie(constant_offset)));
3782-
ASSERT(constant_map.Release().raw() == H.constants().raw());
3779+
Fragment result = Constant(Object::ZoneHandle(
3780+
Z, constant_evaluator_.EvaluateConstantExpression(constant_offset)));
37833781
return result;
37843782
}
37853783

runtime/vm/compiler/frontend/kernel_translation_helper.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ TranslationHelper::TranslationHelper(Thread* thread)
3232
metadata_payloads_(ExternalTypedData::Handle(Z)),
3333
metadata_mappings_(ExternalTypedData::Handle(Z)),
3434
constants_(Array::Handle(Z)),
35+
constants_table_(ExternalTypedData::Handle(Z)),
3536
info_(KernelProgramInfo::Handle(Z)),
3637
name_index_handle_(Smi::Handle(Z)) {}
3738

@@ -46,6 +47,7 @@ TranslationHelper::TranslationHelper(Thread* thread, Heap::Space space)
4647
metadata_payloads_(ExternalTypedData::Handle(Z)),
4748
metadata_mappings_(ExternalTypedData::Handle(Z)),
4849
constants_(Array::Handle(Z)),
50+
constants_table_(ExternalTypedData::Handle(Z)),
4951
info_(KernelProgramInfo::Handle(Z)),
5052
name_index_handle_(Smi::Handle(Z)) {}
5153

@@ -79,6 +81,7 @@ void TranslationHelper::InitFromKernelProgramInfo(
7981
SetMetadataPayloads(ExternalTypedData::Handle(Z, info.metadata_payloads()));
8082
SetMetadataMappings(ExternalTypedData::Handle(Z, info.metadata_mappings()));
8183
SetConstants(Array::Handle(Z, info.constants()));
84+
SetConstantsTable(ExternalTypedData::Handle(Z, info.constants_table()));
8285
SetKernelProgramInfo(info);
8386
}
8487

@@ -126,6 +129,12 @@ void TranslationHelper::SetConstants(const Array& constants) {
126129
constants_ = constants.raw();
127130
}
128131

132+
void TranslationHelper::SetConstantsTable(
133+
const ExternalTypedData& constants_table) {
134+
ASSERT(constants_table_.IsNull());
135+
constants_table_ = constants_table.raw();
136+
}
137+
129138
void TranslationHelper::SetKernelProgramInfo(const KernelProgramInfo& info) {
130139
info_ = info.raw();
131140
}

runtime/vm/compiler/frontend/kernel_translation_helper.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,24 +41,35 @@ class TranslationHelper {
4141
Heap::Space allocation_space() { return allocation_space_; }
4242

4343
// Access to strings.
44-
const TypedData& string_offsets() { return string_offsets_; }
44+
const TypedData& string_offsets() const { return string_offsets_; }
4545
void SetStringOffsets(const TypedData& string_offsets);
4646

47-
const ExternalTypedData& string_data() { return string_data_; }
47+
const ExternalTypedData& string_data() const { return string_data_; }
4848
void SetStringData(const ExternalTypedData& string_data);
4949

50-
const TypedData& canonical_names() { return canonical_names_; }
50+
const TypedData& canonical_names() const { return canonical_names_; }
5151
void SetCanonicalNames(const TypedData& canonical_names);
5252

53-
const ExternalTypedData& metadata_payloads() { return metadata_payloads_; }
53+
const ExternalTypedData& metadata_payloads() const {
54+
return metadata_payloads_;
55+
}
5456
void SetMetadataPayloads(const ExternalTypedData& metadata_payloads);
5557

56-
const ExternalTypedData& metadata_mappings() { return metadata_mappings_; }
58+
const ExternalTypedData& metadata_mappings() const {
59+
return metadata_mappings_;
60+
}
5761
void SetMetadataMappings(const ExternalTypedData& metadata_mappings);
5862

63+
// Access to previously evaluated constants from the constants table.
5964
const Array& constants() { return constants_; }
6065
void SetConstants(const Array& constants);
6166

67+
// Access to the raw bytes of the constants table.
68+
const ExternalTypedData& constants_table() const { return constants_table_; }
69+
void SetConstantsTable(const ExternalTypedData& constants_table);
70+
71+
KernelProgramInfo& info() { return info_; }
72+
6273
RawGrowableObjectArray* EnsurePotentialPragmaFunctions();
6374

6475
void SetKernelProgramInfo(const KernelProgramInfo& info);
@@ -206,6 +217,7 @@ class TranslationHelper {
206217
ExternalTypedData& metadata_payloads_;
207218
ExternalTypedData& metadata_mappings_;
208219
Array& constants_;
220+
ExternalTypedData& constants_table_;
209221
KernelProgramInfo& info_;
210222
Smi& name_index_handle_;
211223

0 commit comments

Comments
 (0)