Skip to content

Commit bbb5e73

Browse files
alexmarkovCommit Queue
authored andcommitted
[vm,dyn_modules] Initial support for hot reloading bytecode
TEST=ci Change-Id: I879ff1c085ee06dda7836d01e2018d93e075f132 Cq-Include-Trybots: luci.dart.try:vm-aot-dyn-linux-debug-x64-try,vm-aot-dyn-linux-product-x64-try,vm-dyn-linux-debug-x64-try,vm-reload-linux-debug-x64-try,vm-reload-linux-release-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/439803 Reviewed-by: Slava Egorov <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent 8a38216 commit bbb5e73

File tree

12 files changed

+381
-138
lines changed

12 files changed

+381
-138
lines changed

pkg/dart2bytecode/bin/kernel_service.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@ Uint8List _generateBytecode(
2929
hierarchy: hierarchy,
3030
target: target,
3131
options: BytecodeOptions(
32-
enableAsserts: enableAsserts,
33-
emitSourcePositions: true,
34-
emitLocalVarInfo: true));
32+
enableAsserts: enableAsserts,
33+
emitSourcePositions: true,
34+
emitLocalVarInfo: true,
35+
emitInstanceFieldInitializers: true,
36+
));
3537
return byteSink.builder.takeBytes();
3638
}
3739

runtime/vm/bytecode_reader.cc

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ BytecodeLoader::~BytecodeLoader() {
8484
FunctionPtr BytecodeLoader::LoadBytecode() {
8585
ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
8686

87-
BytecodeReaderHelper component_reader(thread_, binary_);
88-
bytecode_component_array_ = component_reader.ReadBytecodeComponent();
87+
if (bytecode_component_array_.IsNull()) {
88+
BytecodeReaderHelper component_reader(thread_, binary_);
89+
bytecode_component_array_ = component_reader.ReadBytecodeComponent();
90+
}
8991

9092
BytecodeComponentData bytecode_component(bytecode_component_array_);
9193
BytecodeReaderHelper bytecode_reader(thread_, &bytecode_component);
@@ -108,7 +110,7 @@ void BytecodeLoader::SetOffset(const Object& obj, intptr_t offset) {
108110
bytecode_offsets_map_ = map.Release().ptr();
109111
}
110112

111-
intptr_t BytecodeLoader::GetOffset(const Object& obj) {
113+
intptr_t BytecodeLoader::GetOffset(const Object& obj) const {
112114
BytecodeOffsetsMap map(bytecode_offsets_map_.ptr());
113115
const auto value = map.GetOrNull(obj);
114116
ASSERT(value != Object::null());
@@ -117,6 +119,41 @@ intptr_t BytecodeLoader::GetOffset(const Object& obj) {
117119
return offset;
118120
}
119121

122+
bool BytecodeLoader::HasOffset(const Object& obj) const {
123+
BytecodeOffsetsMap map(bytecode_offsets_map_.ptr());
124+
const auto value = map.GetOrNull(obj);
125+
ASSERT(map.Release().ptr() == bytecode_offsets_map_.ptr());
126+
return value != Object::null();
127+
}
128+
129+
void BytecodeLoader::FindModifiedLibraries(BitVector* modified_libs,
130+
intptr_t* p_num_libraries,
131+
intptr_t* p_num_classes,
132+
intptr_t* p_num_procedures) {
133+
if (bytecode_component_array_.IsNull()) {
134+
BytecodeReaderHelper component_reader(thread_, binary_);
135+
bytecode_component_array_ = component_reader.ReadBytecodeComponent();
136+
}
137+
138+
BytecodeComponentData bytecode_component(bytecode_component_array_);
139+
BytecodeReaderHelper bytecode_reader(thread_, &bytecode_component);
140+
AlternativeReadingScope alt(&bytecode_reader.reader(),
141+
bytecode_component.GetLibraryIndexOffset());
142+
143+
bytecode_reader.FindModifiedLibraries(modified_libs,
144+
bytecode_component.GetNumLibraries());
145+
146+
if (p_num_libraries != nullptr) {
147+
*p_num_libraries = bytecode_component.GetNumLibraries();
148+
}
149+
if (p_num_classes != nullptr) {
150+
*p_num_classes = bytecode_component.GetNumClasses();
151+
}
152+
if (p_num_procedures != nullptr) {
153+
*p_num_procedures = bytecode_component.GetNumCodes();
154+
}
155+
}
156+
120157
BytecodeReaderHelper::BytecodeReaderHelper(Thread* thread,
121158
const TypedDataBase& typed_data)
122159
: reader_(typed_data),
@@ -755,8 +792,6 @@ void BytecodeReaderHelper::ReadLocalVariables(const Bytecode& bytecode,
755792
}
756793

757794
ArrayPtr BytecodeReaderHelper::ReadBytecodeComponent() {
758-
ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
759-
760795
AlternativeReadingScope alt(&reader_, 0);
761796

762797
const intptr_t start_offset = reader_.offset();
@@ -1779,7 +1814,7 @@ void BytecodeReaderHelper::ReadFieldDeclarations(const Class& cls,
17791814
/* is_reflectable = */ false,
17801815
/* is_late = */ false, cls, Object::dynamic_type(),
17811816
TokenPosition::kNoSource, TokenPosition::kNoSource);
1782-
1817+
IG->RegisterStaticField(field, Object::null_object());
17831818
fields.SetAt(num_fields, field);
17841819
}
17851820

@@ -2284,17 +2319,35 @@ void BytecodeReaderHelper::ReadLibraryDeclarations(intptr_t num_libraries) {
22842319
members = cls.fields();
22852320
for (intptr_t j = 0, m = members.Length(); j < m; ++j) {
22862321
field ^= members.At(j);
2287-
if ((field.is_static() || field.is_late()) &&
2288-
field.has_nontrivial_initializer()) {
2289-
function = field.EnsureInitializerFunction();
2290-
if (!function.HasBytecode()) {
2291-
ReadCode(function, thread_->bytecode_loader()->GetOffset(field));
2322+
if (field.has_nontrivial_initializer()) {
2323+
if (field.is_static() || field.is_late() ||
2324+
thread_->bytecode_loader()->HasOffset(field)) {
2325+
function = field.EnsureInitializerFunction();
2326+
if (!function.HasBytecode()) {
2327+
ReadCode(function, thread_->bytecode_loader()->GetOffset(field));
2328+
}
22922329
}
22932330
}
22942331
}
22952332
}
22962333
}
22972334

2335+
void BytecodeReaderHelper::FindModifiedLibraries(BitVector* modified_libs,
2336+
intptr_t num_libraries) {
2337+
auto& uri = String::Handle(Z);
2338+
auto& lib = Library::Handle(Z);
2339+
for (intptr_t i = 0; i < num_libraries; ++i) {
2340+
uri ^= ReadObject();
2341+
reader_.ReadUInt(); // Skip offset.
2342+
2343+
lib = Library::LookupLibrary(thread_, uri);
2344+
if (!lib.IsNull() && !lib.is_dart_scheme()) {
2345+
// This is a library that already exists so mark it as being modified.
2346+
modified_libs->Add(lib.index());
2347+
}
2348+
}
2349+
}
2350+
22982351
void BytecodeReaderHelper::ReadParameterCovariance(
22992352
const Function& function,
23002353
intptr_t code_offset,

runtime/vm/bytecode_reader.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ class BytecodeLoader {
3131
}
3232

3333
void SetOffset(const Object& obj, intptr_t offset);
34-
intptr_t GetOffset(const Object& obj);
34+
intptr_t GetOffset(const Object& obj) const;
35+
bool HasOffset(const Object& obj) const;
36+
37+
void FindModifiedLibraries(BitVector* modified_libs,
38+
intptr_t* p_num_libraries,
39+
intptr_t* p_num_classes,
40+
intptr_t* p_num_procedures);
3541

3642
private:
3743
Thread* thread_;
@@ -204,6 +210,7 @@ class BytecodeReaderHelper : public ValueObject {
204210
void ReadLibraryDeclaration(const Library& library,
205211
const GrowableObjectArray& pending_classes);
206212
void ReadLibraryDeclarations(intptr_t num_libraries);
213+
void FindModifiedLibraries(BitVector* modified_libs, intptr_t num_libraries);
207214

208215
LibraryPtr ReadMain();
209216

0 commit comments

Comments
 (0)