mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[vm] Toward deterministic builds.
- Remove random build-id. - Replace build time in embedded version string with commit time. - Remove timestamps from Observatory tarball. - Zero-initialize skipped bytes in snapshot streams. - Fix uninitialized fields in PatchClass, Script and Library. - Disable (under flag) random identity hashes and concurrent GC. Bug: https://github.com/dart-lang/sdk/issues/31427 Change-Id: I3e95de679c8372841cd27ca60df78d9b00ffbfe1 Reviewed-on: https://dart-review.googlesource.com/22901 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Zach Anderson <zra@google.com>
This commit is contained in:
parent
40c3e129c2
commit
d366f9619a
|
@ -234,6 +234,7 @@ config("compiler") {
|
||||||
"-Wl,-z,noexecstack",
|
"-Wl,-z,noexecstack",
|
||||||
"-Wl,-z,now",
|
"-Wl,-z,now",
|
||||||
"-Wl,-z,relro",
|
"-Wl,-z,relro",
|
||||||
|
"-Wl,--build-id=none",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,10 +232,10 @@ template("build_libdart_builtin") {
|
||||||
}
|
}
|
||||||
static_library(target_name) {
|
static_library(target_name) {
|
||||||
configs += [
|
configs += [
|
||||||
"..:dart_arch_config",
|
"..:dart_arch_config",
|
||||||
"..:dart_config",
|
"..:dart_config",
|
||||||
"..:dart_os_config",
|
"..:dart_os_config",
|
||||||
] + extra_configs
|
] + extra_configs
|
||||||
if (is_fuchsia) {
|
if (is_fuchsia) {
|
||||||
configs -= [ "//build/config:symbol_visibility_hidden" ]
|
configs -= [ "//build/config:symbol_visibility_hidden" ]
|
||||||
}
|
}
|
||||||
|
@ -404,9 +404,7 @@ template("build_gen_snapshot_dart_io") {
|
||||||
configs -= [ "//build/config:symbol_visibility_hidden" ]
|
configs -= [ "//build/config:symbol_visibility_hidden" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
deps += [
|
deps += [ "$dart_zlib_path" ]
|
||||||
"$dart_zlib_path",
|
|
||||||
]
|
|
||||||
|
|
||||||
custom_sources_filter = [
|
custom_sources_filter = [
|
||||||
"*_test.cc",
|
"*_test.cc",
|
||||||
|
@ -459,10 +457,10 @@ template("dart_io") {
|
||||||
}
|
}
|
||||||
source_set(target_name) {
|
source_set(target_name) {
|
||||||
configs += [
|
configs += [
|
||||||
"..:dart_arch_config",
|
"..:dart_arch_config",
|
||||||
"..:dart_config",
|
"..:dart_config",
|
||||||
"..:dart_os_config",
|
"..:dart_os_config",
|
||||||
] + extra_configs
|
] + extra_configs
|
||||||
if (is_fuchsia) {
|
if (is_fuchsia) {
|
||||||
configs -= [ "//build/config:symbol_visibility_hidden" ]
|
configs -= [ "//build/config:symbol_visibility_hidden" ]
|
||||||
}
|
}
|
||||||
|
@ -569,6 +567,7 @@ compiled_action("generate_snapshot_bin") {
|
||||||
]
|
]
|
||||||
tool = ":gen_snapshot"
|
tool = ":gen_snapshot"
|
||||||
args = [
|
args = [
|
||||||
|
"--deterministic",
|
||||||
"--snapshot_kind=" + dart_core_snapshot_kind,
|
"--snapshot_kind=" + dart_core_snapshot_kind,
|
||||||
"--vm_snapshot_data=" + rebase_path(vm_snapshot_data, root_build_dir),
|
"--vm_snapshot_data=" + rebase_path(vm_snapshot_data, root_build_dir),
|
||||||
"--vm_snapshot_instructions=" +
|
"--vm_snapshot_instructions=" +
|
||||||
|
@ -946,15 +945,14 @@ if (is_fuchsia) {
|
||||||
package("dart_tests") {
|
package("dart_tests") {
|
||||||
system_image = true
|
system_image = true
|
||||||
|
|
||||||
deps = [ ":hello_fuchsia" ]
|
deps = [
|
||||||
|
":hello_fuchsia",
|
||||||
binaries = [
|
|
||||||
{
|
|
||||||
name = "hello_fuchsia.dart"
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
}
|
|
||||||
|
|
||||||
|
binaries = [ {
|
||||||
|
name = "hello_fuchsia.dart"
|
||||||
|
} ]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
executable("process_test") {
|
executable("process_test") {
|
||||||
|
|
|
@ -14,11 +14,10 @@ from optparse import OptionParser
|
||||||
from datetime import date
|
from datetime import date
|
||||||
import tarfile
|
import tarfile
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import gzip
|
||||||
|
|
||||||
def makeArchive(tar_path, client_root, compress, files):
|
def makeArchive(tar_path, client_root, compress, files):
|
||||||
mode_string = 'w'
|
mode_string = 'w'
|
||||||
if compress:
|
|
||||||
mode_string = 'w:gz'
|
|
||||||
tar = tarfile.open(tar_path, mode=mode_string)
|
tar = tarfile.open(tar_path, mode=mode_string)
|
||||||
for input_file_name in files:
|
for input_file_name in files:
|
||||||
# Chop off client_root.
|
# Chop off client_root.
|
||||||
|
@ -30,9 +29,18 @@ def makeArchive(tar_path, client_root, compress, files):
|
||||||
tarInfo = tarfile.TarInfo(name=archive_file_name)
|
tarInfo = tarfile.TarInfo(name=archive_file_name)
|
||||||
input_file.seek(0,2)
|
input_file.seek(0,2)
|
||||||
tarInfo.size = input_file.tell()
|
tarInfo.size = input_file.tell()
|
||||||
|
tarInfo.mtime = 0 # For deterministic builds.
|
||||||
input_file.seek(0)
|
input_file.seek(0)
|
||||||
tar.addfile(tarInfo, fileobj=input_file)
|
tar.addfile(tarInfo, fileobj=input_file)
|
||||||
tar.close()
|
tar.close()
|
||||||
|
if compress:
|
||||||
|
with open(tar_path, "rb") as fin:
|
||||||
|
uncompressed = fin.read()
|
||||||
|
with open(tar_path, "wb") as fout:
|
||||||
|
# mtime=0 for deterministic builds.
|
||||||
|
gz = gzip.GzipFile(fileobj=fout, mode="wb", filename="", mtime=0)
|
||||||
|
gz.write(uncompressed)
|
||||||
|
gz.close()
|
||||||
|
|
||||||
def writeCCFile(output_file,
|
def writeCCFile(output_file,
|
||||||
outer_namespace,
|
outer_namespace,
|
||||||
|
|
|
@ -186,7 +186,7 @@ class Serializer : public StackResource {
|
||||||
|
|
||||||
void ReserveHeader() {
|
void ReserveHeader() {
|
||||||
// Make room for recording snapshot buffer size.
|
// Make room for recording snapshot buffer size.
|
||||||
stream_.set_current(stream_.buffer() + Snapshot::kHeaderSize);
|
stream_.SetPosition(Snapshot::kHeaderSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillHeader(Snapshot::Kind kind) {
|
void FillHeader(Snapshot::Kind kind) {
|
||||||
|
|
|
@ -116,6 +116,7 @@ static void PrecompilationModeHandler(bool value) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FLAG_background_compilation = false;
|
FLAG_background_compilation = false;
|
||||||
|
FLAG_collect_code = false;
|
||||||
FLAG_enable_mirrors = false;
|
FLAG_enable_mirrors = false;
|
||||||
FLAG_fields_may_be_reset = true;
|
FLAG_fields_may_be_reset = true;
|
||||||
FLAG_interpret_irregexp = true;
|
FLAG_interpret_irregexp = true;
|
||||||
|
@ -136,7 +137,6 @@ static void PrecompilationModeHandler(bool value) {
|
||||||
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
|
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
|
||||||
// Set flags affecting runtime accordingly for dart_bootstrap.
|
// Set flags affecting runtime accordingly for dart_bootstrap.
|
||||||
// These flags are constants with PRODUCT and DART_PRECOMPILED_RUNTIME.
|
// These flags are constants with PRODUCT and DART_PRECOMPILED_RUNTIME.
|
||||||
FLAG_collect_code = false;
|
|
||||||
FLAG_deoptimize_alot = false; // Used in some tests.
|
FLAG_deoptimize_alot = false; // Used in some tests.
|
||||||
FLAG_deoptimize_every = 0; // Used in some tests.
|
FLAG_deoptimize_every = 0; // Used in some tests.
|
||||||
FLAG_load_deferred_eagerly = true;
|
FLAG_load_deferred_eagerly = true;
|
||||||
|
|
|
@ -74,7 +74,6 @@ class ReadStream : public ValueObject {
|
||||||
intptr_t ReadUnsigned() { return Read<intptr_t>(kEndUnsignedByteMarker); }
|
intptr_t ReadUnsigned() { return Read<intptr_t>(kEndUnsignedByteMarker); }
|
||||||
|
|
||||||
intptr_t Position() const { return current_ - buffer_; }
|
intptr_t Position() const { return current_ - buffer_; }
|
||||||
|
|
||||||
void SetPosition(intptr_t value) {
|
void SetPosition(intptr_t value) {
|
||||||
ASSERT((end_ - buffer_) > value);
|
ASSERT((end_ - buffer_) > value);
|
||||||
current_ = buffer_ + value;
|
current_ = buffer_ + value;
|
||||||
|
@ -312,12 +311,14 @@ class WriteStream : public ValueObject {
|
||||||
void set_buffer(uint8_t* value) { *buffer_ = value; }
|
void set_buffer(uint8_t* value) { *buffer_ = value; }
|
||||||
intptr_t bytes_written() const { return current_ - *buffer_; }
|
intptr_t bytes_written() const { return current_ - *buffer_; }
|
||||||
|
|
||||||
void set_current(uint8_t* value) { current_ = value; }
|
intptr_t Position() const { return current_ - *buffer_; }
|
||||||
|
void SetPosition(intptr_t value) { current_ = *buffer_ + value; }
|
||||||
|
|
||||||
void Align(intptr_t alignment) {
|
void Align(intptr_t alignment) {
|
||||||
intptr_t position = current_ - *buffer_;
|
intptr_t position_before = Position();
|
||||||
position = Utils::RoundUp(position, alignment);
|
intptr_t position_after = Utils::RoundUp(position_before, alignment);
|
||||||
current_ = *buffer_ + position;
|
memset(current_, 0, position_after - position_before);
|
||||||
|
SetPosition(position_after);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int N, typename T>
|
template <int N, typename T>
|
||||||
|
|
|
@ -53,11 +53,10 @@
|
||||||
R(break_at_isolate_spawn, false, bool, false, \
|
R(break_at_isolate_spawn, false, bool, false, \
|
||||||
"Insert a one-time breakpoint at the entrypoint for all spawned isolates") \
|
"Insert a one-time breakpoint at the entrypoint for all spawned isolates") \
|
||||||
P(causal_async_stacks, bool, !USING_PRODUCT, "Improved async stacks") \
|
P(causal_async_stacks, bool, !USING_PRODUCT, "Improved async stacks") \
|
||||||
C(collect_code, false, true, bool, true, \
|
P(collect_code, bool, true, "Attempt to GC infrequently used code.") \
|
||||||
"Attempt to GC infrequently used code.") \
|
|
||||||
P(collect_dynamic_function_names, bool, true, \
|
P(collect_dynamic_function_names, bool, true, \
|
||||||
"Collects all dynamic function names to identify unique targets") \
|
"Collects all dynamic function names to identify unique targets") \
|
||||||
R(concurrent_sweep, USING_MULTICORE, bool, USING_MULTICORE, \
|
P(concurrent_sweep, bool, USING_MULTICORE, \
|
||||||
"Concurrent sweep for old generation.") \
|
"Concurrent sweep for old generation.") \
|
||||||
R(dedup_instructions, true, bool, false, \
|
R(dedup_instructions, true, bool, false, \
|
||||||
"Canonicalize instructions when precompiling.") \
|
"Canonicalize instructions when precompiling.") \
|
||||||
|
|
|
@ -80,6 +80,26 @@ DEFINE_FLAG_HANDLER(CheckedModeHandler,
|
||||||
DEFINE_FLAG_HANDLER(CheckedModeHandler, checked, "Enable checked mode.");
|
DEFINE_FLAG_HANDLER(CheckedModeHandler, checked, "Enable checked mode.");
|
||||||
#endif // !defined(PRODUCT)
|
#endif // !defined(PRODUCT)
|
||||||
|
|
||||||
|
static void DeterministicModeHandler(bool value) {
|
||||||
|
if (value) {
|
||||||
|
FLAG_background_compilation = false;
|
||||||
|
FLAG_collect_code = false;
|
||||||
|
// Parallel marking doesn't introduce non-determinism in the object
|
||||||
|
// iteration order.
|
||||||
|
FLAG_concurrent_sweep = false;
|
||||||
|
FLAG_random_seed = 0x44617274; // "Dart"
|
||||||
|
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
|
||||||
|
FLAG_load_deferred_eagerly = true;
|
||||||
|
#else
|
||||||
|
COMPILE_ASSERT(FLAG_load_deferred_eagerly);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_FLAG_HANDLER(DeterministicModeHandler,
|
||||||
|
deterministic,
|
||||||
|
"Enable deterministic mode.");
|
||||||
|
|
||||||
// Quick access to the locally defined thread() and isolate() methods.
|
// Quick access to the locally defined thread() and isolate() methods.
|
||||||
#define T (thread())
|
#define T (thread())
|
||||||
#define I (isolate())
|
#define I (isolate())
|
||||||
|
|
|
@ -2099,10 +2099,15 @@ RawClass* Class::New() {
|
||||||
}
|
}
|
||||||
FakeObject fake;
|
FakeObject fake;
|
||||||
result.set_handle_vtable(fake.vtable());
|
result.set_handle_vtable(fake.vtable());
|
||||||
|
result.set_token_pos(TokenPosition::kNoSource);
|
||||||
result.set_instance_size(FakeObject::InstanceSize());
|
result.set_instance_size(FakeObject::InstanceSize());
|
||||||
|
result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
|
||||||
result.set_next_field_offset(FakeObject::NextFieldOffset());
|
result.set_next_field_offset(FakeObject::NextFieldOffset());
|
||||||
COMPILE_ASSERT((FakeObject::kClassId != kInstanceCid));
|
COMPILE_ASSERT((FakeObject::kClassId != kInstanceCid));
|
||||||
result.set_id(FakeObject::kClassId);
|
result.set_id(FakeObject::kClassId);
|
||||||
|
result.set_num_type_arguments(0);
|
||||||
|
result.set_num_own_type_arguments(0);
|
||||||
|
result.set_num_native_fields(0);
|
||||||
result.set_state_bits(0);
|
result.set_state_bits(0);
|
||||||
if ((FakeObject::kClassId < kInstanceCid) ||
|
if ((FakeObject::kClassId < kInstanceCid) ||
|
||||||
(FakeObject::kClassId == kTypeArgumentsCid)) {
|
(FakeObject::kClassId == kTypeArgumentsCid)) {
|
||||||
|
@ -2114,11 +2119,6 @@ RawClass* Class::New() {
|
||||||
// references, but do not recompute size.
|
// references, but do not recompute size.
|
||||||
result.set_is_prefinalized();
|
result.set_is_prefinalized();
|
||||||
}
|
}
|
||||||
result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
|
|
||||||
result.set_num_type_arguments(0);
|
|
||||||
result.set_num_own_type_arguments(0);
|
|
||||||
result.set_num_native_fields(0);
|
|
||||||
result.set_token_pos(TokenPosition::kNoSource);
|
|
||||||
result.set_kernel_offset(-1);
|
result.set_kernel_offset(-1);
|
||||||
result.InitEmptyFields();
|
result.InitEmptyFields();
|
||||||
Isolate::Current()->RegisterClass(result);
|
Isolate::Current()->RegisterClass(result);
|
||||||
|
@ -3240,15 +3240,15 @@ RawClass* Class::NewCommon(intptr_t index) {
|
||||||
FakeInstance fake;
|
FakeInstance fake;
|
||||||
ASSERT(fake.IsInstance());
|
ASSERT(fake.IsInstance());
|
||||||
result.set_handle_vtable(fake.vtable());
|
result.set_handle_vtable(fake.vtable());
|
||||||
|
result.set_token_pos(TokenPosition::kNoSource);
|
||||||
result.set_instance_size(FakeInstance::InstanceSize());
|
result.set_instance_size(FakeInstance::InstanceSize());
|
||||||
|
result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
|
||||||
result.set_next_field_offset(FakeInstance::NextFieldOffset());
|
result.set_next_field_offset(FakeInstance::NextFieldOffset());
|
||||||
result.set_id(index);
|
result.set_id(index);
|
||||||
result.set_state_bits(0);
|
|
||||||
result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
|
|
||||||
result.set_num_type_arguments(kUnknownNumTypeArguments);
|
result.set_num_type_arguments(kUnknownNumTypeArguments);
|
||||||
result.set_num_own_type_arguments(kUnknownNumTypeArguments);
|
result.set_num_own_type_arguments(kUnknownNumTypeArguments);
|
||||||
result.set_num_native_fields(0);
|
result.set_num_native_fields(0);
|
||||||
result.set_token_pos(TokenPosition::kNoSource);
|
result.set_state_bits(0);
|
||||||
result.InitEmptyFields();
|
result.InitEmptyFields();
|
||||||
return result.raw();
|
return result.raw();
|
||||||
}
|
}
|
||||||
|
@ -5212,6 +5212,7 @@ RawPatchClass* PatchClass::New(const Class& patched_class,
|
||||||
result.set_patched_class(patched_class);
|
result.set_patched_class(patched_class);
|
||||||
result.set_origin_class(origin_class);
|
result.set_origin_class(origin_class);
|
||||||
result.set_script(Script::Handle(origin_class.script()));
|
result.set_script(Script::Handle(origin_class.script()));
|
||||||
|
result.set_library_kernel_offset(-1);
|
||||||
return result.raw();
|
return result.raw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5221,6 +5222,7 @@ RawPatchClass* PatchClass::New(const Class& patched_class,
|
||||||
result.set_patched_class(patched_class);
|
result.set_patched_class(patched_class);
|
||||||
result.set_origin_class(patched_class);
|
result.set_origin_class(patched_class);
|
||||||
result.set_script(script);
|
result.set_script(script);
|
||||||
|
result.set_library_kernel_offset(-1);
|
||||||
return result.raw();
|
return result.raw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9843,10 +9845,11 @@ RawScript* Script::New(const String& url,
|
||||||
result.set_resolved_url(
|
result.set_resolved_url(
|
||||||
String::Handle(zone, Symbols::New(thread, resolved_url)));
|
String::Handle(zone, Symbols::New(thread, resolved_url)));
|
||||||
result.set_source(source);
|
result.set_source(source);
|
||||||
|
result.SetLocationOffset(0, 0);
|
||||||
result.set_kind(kind);
|
result.set_kind(kind);
|
||||||
|
result.set_kernel_script_index(0);
|
||||||
result.set_load_timestamp(
|
result.set_load_timestamp(
|
||||||
FLAG_remove_script_timestamps_for_test ? 0 : OS::GetCurrentTimeMillis());
|
FLAG_remove_script_timestamps_for_test ? 0 : OS::GetCurrentTimeMillis());
|
||||||
result.SetLocationOffset(0, 0);
|
|
||||||
return result.raw();
|
return result.raw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11099,6 +11102,7 @@ RawLibrary* Library::NewLibraryHelper(const String& url, bool import_core_lib) {
|
||||||
result.set_debuggable(true);
|
result.set_debuggable(true);
|
||||||
}
|
}
|
||||||
result.set_is_dart_scheme(dart_scheme);
|
result.set_is_dart_scheme(dart_scheme);
|
||||||
|
result.set_kernel_offset(-1);
|
||||||
result.StoreNonPointer(&result.raw_ptr()->load_state_,
|
result.StoreNonPointer(&result.raw_ptr()->load_state_,
|
||||||
RawLibrary::kAllocated);
|
RawLibrary::kAllocated);
|
||||||
result.StoreNonPointer(&result.raw_ptr()->index_, -1);
|
result.StoreNonPointer(&result.raw_ptr()->index_, -1);
|
||||||
|
|
|
@ -3792,7 +3792,7 @@ class Library : public Object {
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void set_kernel_offset(intptr_t offset) {
|
void set_kernel_offset(intptr_t offset) const {
|
||||||
NOT_IN_PRECOMPILED(StoreNonPointer(&raw_ptr()->kernel_offset_, offset));
|
NOT_IN_PRECOMPILED(StoreNonPointer(&raw_ptr()->kernel_offset_, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,8 +130,6 @@ class ObjectPointerVisitor;
|
||||||
|
|
||||||
// The object store is a per isolate instance which stores references to
|
// The object store is a per isolate instance which stores references to
|
||||||
// objects used by the VM.
|
// objects used by the VM.
|
||||||
// TODO(iposva): Move the actual store into the object heap for quick handling
|
|
||||||
// by snapshots eventually.
|
|
||||||
class ObjectStore {
|
class ObjectStore {
|
||||||
public:
|
public:
|
||||||
enum BootstrapLibraryId {
|
enum BootstrapLibraryId {
|
||||||
|
|
|
@ -9,7 +9,10 @@
|
||||||
|
|
||||||
namespace dart {
|
namespace dart {
|
||||||
|
|
||||||
DEFINE_FLAG(int, random_seed, 0, "Override the random seed for debugging.");
|
DEFINE_FLAG(uint64_t,
|
||||||
|
random_seed,
|
||||||
|
0,
|
||||||
|
"Override the random seed for debugging.");
|
||||||
|
|
||||||
Random::Random() {
|
Random::Random() {
|
||||||
uint64_t seed = FLAG_random_seed;
|
uint64_t seed = FLAG_random_seed;
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
#define RUNTIME_VM_RANDOM_H_
|
#define RUNTIME_VM_RANDOM_H_
|
||||||
|
|
||||||
#include "vm/allocation.h"
|
#include "vm/allocation.h"
|
||||||
|
#include "vm/flags.h"
|
||||||
#include "vm/globals.h"
|
#include "vm/globals.h"
|
||||||
|
|
||||||
namespace dart {
|
namespace dart {
|
||||||
|
|
||||||
|
DECLARE_FLAG(uint64_t, random_seed);
|
||||||
|
|
||||||
class Random {
|
class Random {
|
||||||
public:
|
public:
|
||||||
Random();
|
Random();
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
|
|
||||||
namespace dart {
|
namespace dart {
|
||||||
|
|
||||||
DECLARE_FLAG(bool, remove_script_timestamps_for_test);
|
|
||||||
|
|
||||||
#define OFFSET_OF_FROM(obj) \
|
#define OFFSET_OF_FROM(obj) \
|
||||||
obj.raw()->from() - reinterpret_cast<RawObject**>(obj.raw()->ptr())
|
obj.raw()->from() - reinterpret_cast<RawObject**>(obj.raw()->ptr())
|
||||||
|
|
||||||
|
@ -1049,6 +1047,7 @@ RawScript* Script::ReadFrom(SnapshotReader* reader,
|
||||||
script.StoreNonPointer(&script.raw_ptr()->kind_, reader->Read<int8_t>());
|
script.StoreNonPointer(&script.raw_ptr()->kind_, reader->Read<int8_t>());
|
||||||
script.StoreNonPointer(&script.raw_ptr()->kernel_script_index_,
|
script.StoreNonPointer(&script.raw_ptr()->kernel_script_index_,
|
||||||
reader->Read<int32_t>());
|
reader->Read<int32_t>());
|
||||||
|
script.StoreNonPointer(&script.raw_ptr()->load_timestamp_, 0);
|
||||||
|
|
||||||
*reader->StringHandle() ^= String::null();
|
*reader->StringHandle() ^= String::null();
|
||||||
script.set_source(*reader->StringHandle());
|
script.set_source(*reader->StringHandle());
|
||||||
|
@ -1065,9 +1064,6 @@ RawScript* Script::ReadFrom(SnapshotReader* reader,
|
||||||
reader->PassiveObjectHandle()->raw());
|
reader->PassiveObjectHandle()->raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
script.set_load_timestamp(
|
|
||||||
FLAG_remove_script_timestamps_for_test ? 0 : OS::GetCurrentTimeMillis());
|
|
||||||
|
|
||||||
return script.raw();
|
return script.raw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -570,7 +570,7 @@ class BaseWriter : public StackResource {
|
||||||
|
|
||||||
void ReserveHeader() {
|
void ReserveHeader() {
|
||||||
// Make room for recording snapshot buffer size.
|
// Make room for recording snapshot buffer size.
|
||||||
stream_.set_current(stream_.buffer() + Snapshot::kHeaderSize);
|
stream_.SetPosition(Snapshot::kHeaderSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillHeader(Snapshot::Kind kind) {
|
void FillHeader(Snapshot::Kind kind) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ const char* Version::CommitString() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Version::snapshot_hash_ = "{{SNAPSHOT_HASH}}";
|
const char* Version::snapshot_hash_ = "{{SNAPSHOT_HASH}}";
|
||||||
const char* Version::str_ = "{{VERSION_STR}} ({{BUILD_TIME}})";
|
const char* Version::str_ = "{{VERSION_STR}} ({{COMMIT_TIME}})";
|
||||||
const char* Version::commit_ = "{{VERSION_STR}}";
|
const char* Version::commit_ = "{{VERSION_STR}}";
|
||||||
|
|
||||||
} // namespace dart
|
} // namespace dart
|
||||||
|
|
|
@ -61,8 +61,10 @@ def makeFile(quiet, output_file, input_file, ignore_svn_revision):
|
||||||
version_string = makeVersionString(quiet, ignore_svn_revision)
|
version_string = makeVersionString(quiet, ignore_svn_revision)
|
||||||
version_cc_text = version_cc_text.replace("{{VERSION_STR}}",
|
version_cc_text = version_cc_text.replace("{{VERSION_STR}}",
|
||||||
version_string)
|
version_string)
|
||||||
version_time = time.ctime(time.time())
|
version_time = utils.GetGitTimestamp()
|
||||||
version_cc_text = version_cc_text.replace("{{BUILD_TIME}}",
|
if version_time == None:
|
||||||
|
version_time = "Unknown timestamp"
|
||||||
|
version_cc_text = version_cc_text.replace("{{COMMIT_TIME}}",
|
||||||
version_time)
|
version_time)
|
||||||
snapshot_hash = makeSnapshotHashString()
|
snapshot_hash = makeSnapshotHashString()
|
||||||
version_cc_text = version_cc_text.replace("{{SNAPSHOT_HASH}}",
|
version_cc_text = version_cc_text.replace("{{SNAPSHOT_HASH}}",
|
||||||
|
|
|
@ -425,6 +425,16 @@ def GetGitRevision():
|
||||||
return None
|
return None
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
def GetGitTimestamp():
|
||||||
|
p = subprocess.Popen(['git', 'log', '-n', '1', '--pretty=format:%cd'],
|
||||||
|
stdout = subprocess.PIPE,
|
||||||
|
stderr = subprocess.STDOUT, shell=IsWindows(),
|
||||||
|
cwd = DART_DIR)
|
||||||
|
output, _ = p.communicate()
|
||||||
|
if p.wait() != 0:
|
||||||
|
return None
|
||||||
|
return output
|
||||||
|
|
||||||
# To eliminate clashing with older archived builds on bleeding edge we add
|
# To eliminate clashing with older archived builds on bleeding edge we add
|
||||||
# a base number bigger the largest svn revision (this also gives us an easy
|
# a base number bigger the largest svn revision (this also gives us an easy
|
||||||
# way of seeing if an archive comes from git based or svn based commits).
|
# way of seeing if an archive comes from git based or svn based commits).
|
||||||
|
@ -545,6 +555,7 @@ def Main():
|
||||||
print "IsWindows() -> ", IsWindows()
|
print "IsWindows() -> ", IsWindows()
|
||||||
print "GuessVisualStudioPath() -> ", GuessVisualStudioPath()
|
print "GuessVisualStudioPath() -> ", GuessVisualStudioPath()
|
||||||
print "GetGitRevision() -> ", GetGitRevision()
|
print "GetGitRevision() -> ", GetGitRevision()
|
||||||
|
print "GetGitTimestamp() -> ", GetGitTimestamp()
|
||||||
print "GetVersionFileContent() -> ", GetVersionFileContent()
|
print "GetVersionFileContent() -> ", GetVersionFileContent()
|
||||||
print "GetGitNumber() -> ", GetGitNumber()
|
print "GetGitNumber() -> ", GetGitNumber()
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ template("application_snapshot") {
|
||||||
main_file = rebase_path(main_dart)
|
main_file = rebase_path(main_dart)
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
|
"--deterministic",
|
||||||
"--packages=$dot_packages",
|
"--packages=$dot_packages",
|
||||||
"--snapshot=$abs_output",
|
"--snapshot=$abs_output",
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue