Skip to content

Commit e893d11

Browse files
alexmarkovCommit Queue
authored andcommitted
[vm,compiler] Fix serialization of ranges and arguments descriptors
Convert range boundaries with symbolic references to other instructions into constant boundaries to avoid serializing extra references. Specially handle serialization of arguments descriptors which are cached in the VM isolate. TEST=ci Change-Id: Ifab3bb4d9b037aaefd81d38dd93d47cd4b42cf1d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/405571 Commit-Queue: Alexander Markov <[email protected]> Reviewed-by: Slava Egorov <[email protected]>
1 parent d86f6c2 commit e893d11

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

runtime/vm/compiler/backend/il_serializer.cc

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,31 @@ void AliasIdentity::Write(FlowGraphSerializer* s) const {
9898
AliasIdentity::AliasIdentity(FlowGraphDeserializer* d)
9999
: value_(d->Read<intptr_t>()) {}
100100

101+
void ArgumentsDescriptor::Write(FlowGraphSerializer* s) const {
102+
if (IsCached()) {
103+
// Simple argument descriptors are cached in the VM isolate.
104+
// Write them as arguments count and query cache during deserialization.
105+
ASSERT(TypeArgsLen() == 0);
106+
ASSERT(NamedCount() == 0);
107+
ASSERT(Count() == Size());
108+
ASSERT(array_.InVMIsolateHeap());
109+
s->Write<intptr_t>(Count());
110+
} else {
111+
ASSERT(array_.IsCanonical());
112+
ASSERT(!array_.InVMIsolateHeap());
113+
s->Write<intptr_t>(-1);
114+
s->Write<const Array&>(array_);
115+
}
116+
}
117+
118+
ArrayPtr ArgumentsDescriptor::Read(FlowGraphDeserializer* d) {
119+
const intptr_t num_args = d->Read<intptr_t>();
120+
if (num_args < 0) {
121+
return d->Read<const Array&>().ptr();
122+
}
123+
return NewBoxed(0, num_args);
124+
}
125+
101126
void BlockEntryInstr::WriteTo(FlowGraphSerializer* s) {
102127
TemplateInstruction::WriteTo(s);
103128
s->Write<intptr_t>(block_id_);
@@ -850,7 +875,7 @@ void FlowGraphSerializer::WriteTrait<const Function&>::Write(
850875
case UntaggedFunction::kInvokeFieldDispatcher: {
851876
s->Write<const Class&>(Class::Handle(zone, x.Owner()));
852877
s->Write<const String&>(String::Handle(zone, x.name()));
853-
s->Write<const Array&>(Array::Handle(zone, x.saved_args_desc()));
878+
ArgumentsDescriptor(Array::Handle(zone, x.saved_args_desc())).Write(s);
854879
return;
855880
}
856881
case UntaggedFunction::kDynamicInvocationForwarder: {
@@ -926,7 +951,8 @@ const Function& FlowGraphDeserializer::ReadTrait<const Function&>::Read(
926951
case UntaggedFunction::kInvokeFieldDispatcher: {
927952
const Class& owner = d->Read<const Class&>();
928953
const String& target_name = d->Read<const String&>();
929-
const Array& args_desc = d->Read<const Array&>();
954+
const Array& args_desc =
955+
Array::Handle(zone, ArgumentsDescriptor::Read(d));
930956
return Function::ZoneHandle(
931957
zone,
932958
owner.GetInvocationDispatcher(
@@ -1650,7 +1676,8 @@ void FlowGraphSerializer::WriteObjectImpl(const Object& x,
16501676
const auto& icdata = ICData::Cast(x);
16511677
Write<int8_t>(static_cast<int8_t>(icdata.rebind_rule()));
16521678
Write<const Function&>(Function::Handle(Z, icdata.Owner()));
1653-
Write<const Array&>(Array::Handle(Z, icdata.arguments_descriptor()));
1679+
ArgumentsDescriptor(Array::Handle(Z, icdata.arguments_descriptor()))
1680+
.Write(this);
16541681
Write<intptr_t>(icdata.deopt_id());
16551682
Write<intptr_t>(icdata.NumArgsTested());
16561683
if (icdata.rebind_rule() == ICData::kStatic) {
@@ -1940,7 +1967,8 @@ const Object& FlowGraphDeserializer::ReadObjectImpl(intptr_t cid,
19401967
const ICData::RebindRule rebind_rule =
19411968
static_cast<ICData::RebindRule>(Read<int8_t>());
19421969
const auto& owner = Read<const Function&>();
1943-
const auto& arguments_descriptor = Read<const Array&>();
1970+
const auto& arguments_descriptor =
1971+
Array::Handle(Z, ArgumentsDescriptor::Read(this));
19441972
const intptr_t deopt_id = Read<intptr_t>();
19451973
const intptr_t num_args_tested = Read<intptr_t>();
19461974

@@ -2262,14 +2290,17 @@ Range* FlowGraphDeserializer::ReadTrait<Range*>::Read(
22622290
}
22632291

22642292
void Range::Write(FlowGraphSerializer* s) const {
2265-
min_.Write(s);
2266-
max_.Write(s);
2293+
// Drop symbolic range boundaries - they are not useful
2294+
// when flow graph is serialized/deserialized.
2295+
min_.LowerBound().Write(s);
2296+
max_.UpperBound().Write(s);
22672297
}
22682298

22692299
Range::Range(FlowGraphDeserializer* d)
22702300
: min_(RangeBoundary(d)), max_(RangeBoundary(d)) {}
22712301

22722302
void RangeBoundary::Write(FlowGraphSerializer* s) const {
2303+
ASSERT(!IsSymbol());
22732304
s->Write<int8_t>(kind_);
22742305
s->Write<int64_t>(value_);
22752306
s->Write<int64_t>(offset_);

runtime/vm/dart_entry.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,12 @@ const char* ArgumentsDescriptor::ToCString() const {
442442
return buf.buffer();
443443
}
444444

445+
bool ArgumentsDescriptor::IsCached() const {
446+
const intptr_t num_arguments = Count();
447+
return (num_arguments < kCachedDescriptorCount) &&
448+
(array_.ptr() == cached_args_descriptors_[num_arguments]);
449+
}
450+
445451
ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len,
446452
intptr_t num_arguments,
447453
intptr_t size_arguments,

runtime/vm/dart_entry.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ namespace dart {
1515
// Forward declarations.
1616
class Array;
1717
class Closure;
18+
class FlowGraphDeserializer;
19+
class FlowGraphSerializer;
1820
class Function;
1921
class Instance;
2022
class Integer;
@@ -132,6 +134,9 @@ class ArgumentsDescriptor : public ValueObject {
132134
return Array::ContainsCompressedPointers();
133135
}
134136

137+
void Write(FlowGraphSerializer* s) const;
138+
static ArrayPtr Read(FlowGraphDeserializer* d);
139+
135140
private:
136141
// Absolute indices into the array.
137142
// Keep these in sync with the constants in invocation_mirror_patch.dart.
@@ -174,6 +179,8 @@ class ArgumentsDescriptor : public ValueObject {
174179
return kFirstNamedEntryIndex + (index * kNamedEntrySize) + kPositionOffset;
175180
}
176181

182+
bool IsCached() const;
183+
177184
const Array& array_;
178185

179186
// A cache of VM heap allocated arguments descriptors.

0 commit comments

Comments
 (0)