3e599229b9
Currently serializing the ast for kernel is done in two passe: 1) Scan the program to find and index all strings. These are then sorted based on frequency and assigned an id. All string- references are refering to that id. As small numbers use less space in the binary than big numbers, sorting the numbers by frequency saves a certain amount of space. In addition the string indexing is "hijacked" for the "LimitedBinaryPrinter" to also perform some CanonicalName re-indexing. 2) We then serialize the entire thing. This CL gets rid of a pass by not indexing the strings up-front. Whenever it is asked to serialize a string it adds it to the index (if not already there). The serialization is otherwise the same. This means that: 1) Strings are not sorted by frequency, i.e. the binary output size can by bigger (numbers below). 2) The stringindex and canonical names are moved to the end of the binary instead of the front. As we still need it up front for deserialization some additional data is added to the ProgramIndex. 3) The "hijacking" done in "LimitedBinaryPrinter" is replaced by an alternative. 4) We don't spend time on walking the tree twice. The cost is the binary size. Compiling helloworld with fasta, as well as looking at outline.dill, platform.dill and vmservice_io.dill reveals these numbers: * helloworld.dill is 0.657248732% bigger (26573 bytes) * outline.dill is 1.686911399% bigger (9395 bytes) * platform.dill is 0.657062238% bigger (26565 bytes) * vmservice_io.dill is 0.44991899% bigger (19147 bytes) The cost does thus not appear to be very big. The gain is the serialization time. From 20 runs of an instrumented VM/serialization, running numbers through calculations stolens from ministat (https://www.freebsd.org/cgi/man.cgi?query=ministat) reveals the following: * Serialization time: -21.69% +/- 1.44% * Total time spend in relevant parts of bootstrap_nocore.cc, dart_api_impl.cc (Dart_LoadKernel), bootstrap_nocore.cc, dart_api_impl.cc (LoadKernelProgram) as well as serialization: -14.01% +/- 1.58% From 5 runs of "time python tools/test.py -m release -cdartk language -j6" (again run through ministat calculations): * real: -4.18% +/- 0.5% * user: -4.2% +/- 0.29% * sys: No difference at 95% * user+sys: -3.3% +/- 0.36% Change-Id: I1c220eac083496994f0a9f1e2a2445b3707c9a93 Reviewed-on: https://dart-review.googlesource.com/2880 Reviewed-by: Samir Jindel <sjindel@google.com>
50 lines
1.7 KiB
C++
50 lines
1.7 KiB
C++
// Copyright (c) 2016, 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.
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
#include "vm/kernel_binary.h"
|
|
#include "platform/globals.h"
|
|
#include "vm/compiler/frontend/kernel_to_il.h"
|
|
#include "vm/flags.h"
|
|
#include "vm/growable_array.h"
|
|
#include "vm/kernel.h"
|
|
#include "vm/os.h"
|
|
|
|
namespace dart {
|
|
|
|
namespace kernel {
|
|
|
|
Program* Program::ReadFrom(Reader* reader) {
|
|
uint32_t magic = reader->ReadUInt32();
|
|
if (magic != kMagicProgramFile) FATAL("Invalid magic identifier");
|
|
|
|
Program* program = new Program();
|
|
program->kernel_data_ = reader->buffer();
|
|
program->kernel_data_size_ = reader->size();
|
|
|
|
// Read backwards at the end.
|
|
reader->set_offset(reader->size() - (4 * LibraryCountFieldCountFromEnd));
|
|
program->library_count_ = reader->ReadUInt32();
|
|
reader->set_offset(reader->size() - (4 * LibraryCountFieldCountFromEnd) -
|
|
(4 * program->library_count_) -
|
|
(SourceTableFieldCountFromFirstLibraryOffset * 4));
|
|
program->source_table_offset_ = reader->ReadUInt32();
|
|
program->name_table_offset_ = reader->ReadUInt32();
|
|
program->string_table_offset_ = reader->ReadUInt32();
|
|
program->main_method_reference_ = NameIndex(reader->ReadUInt32() - 1);
|
|
|
|
return program;
|
|
}
|
|
|
|
} // namespace kernel
|
|
|
|
kernel::Program* ReadPrecompiledKernelFromBuffer(const uint8_t* buffer,
|
|
intptr_t buffer_length) {
|
|
kernel::Reader reader(buffer, buffer_length);
|
|
return kernel::Program::ReadFrom(&reader);
|
|
}
|
|
|
|
} // namespace dart
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|