[vm] Maintain view-ness of bytecode instructions in snapshots.

Change-Id: Ieb032d55e5b8bab08e7eb3445a356068384dca28
Reviewed-on: https://dart-review.googlesource.com/c/91682
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
This commit is contained in:
Ryan Macnak 2019-01-31 20:10:58 +00:00 committed by commit-bot@chromium.org
parent d4b8e0696d
commit e717ecdc92
10 changed files with 90 additions and 77 deletions

View file

@ -71,7 +71,6 @@ const uint8_t* isolate_snapshot_instructions = NULL;
enum SnapshotKind {
kCore,
kCoreJIT,
kCoreJITAll,
kApp,
kAppJIT,
kAppAOTBlobs,
@ -99,7 +98,6 @@ static const char* kSnapshotKindNames[] = {
// clang-format off
"core",
"core-jit",
"core-jit-all",
"app",
"app-jit",
"app-aot-blobs",
@ -132,6 +130,8 @@ static const char* kSnapshotKindNames[] = {
V(save_obfuscation_map, obfuscation_map_filename)
#define BOOL_OPTIONS_LIST(V) \
V(read_all_bytecode, read_all_bytecode) \
V(compile_all, compile_all) \
V(obfuscate, obfuscate) \
V(verbose, verbose) \
V(version, version) \
@ -286,7 +286,6 @@ static int ParseArguments(int argc,
}
break;
}
case kCoreJITAll:
case kCoreJIT: {
if ((vm_snapshot_data_filename == NULL) ||
(vm_snapshot_instructions_filename == NULL) ||
@ -461,7 +460,6 @@ class DependenciesFileWriter : public ValueObject {
WriteDependenciesWithTarget(isolate_snapshot_data_filename);
// WriteDependenciesWithTarget(isolate_snapshot_instructions_filename);
break;
case kCoreJITAll:
case kCoreJIT:
WriteDependenciesWithTarget(vm_snapshot_data_filename);
// WriteDependenciesWithTarget(vm_snapshot_instructions_filename);
@ -550,16 +548,20 @@ static void CreateAndWriteDependenciesFile() {
dependencies->Clear();
}
static void LoadBytecode() {
if ((Dart_IsVMFlagSet("enable_interpreter") ||
Dart_IsVMFlagSet("use_bytecode_compiler")) &&
((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
static void MaybeLoadCode() {
if (read_all_bytecode &&
((snapshot_kind == kCore) || (snapshot_kind == kCoreJIT) ||
(snapshot_kind == kApp) || (snapshot_kind == kAppJIT))) {
Dart_Handle result = Dart_ReadAllBytecode();
CHECK_RESULT(result);
}
}
static void LoadCompilationTrace() {
if (compile_all &&
((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
Dart_Handle result = Dart_CompileAll();
CHECK_RESULT(result);
}
if ((load_compilation_trace_filename != NULL) &&
((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
uint8_t* buffer = NULL;
@ -568,6 +570,7 @@ static void LoadCompilationTrace() {
Dart_Handle result = Dart_LoadCompilationTrace(buffer, size);
CHECK_RESULT(result);
}
if ((load_type_feedback_filename != NULL) &&
((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
uint8_t* buffer = NULL;
@ -578,13 +581,6 @@ static void LoadCompilationTrace() {
}
}
static void CompileAll() {
if (snapshot_kind == kCoreJITAll) {
Dart_Handle result = Dart_CompileAll();
CHECK_RESULT(result);
}
}
static void CreateAndWriteCoreSnapshot() {
ASSERT(snapshot_kind == kCore);
ASSERT(vm_snapshot_data_filename != NULL);
@ -645,7 +641,7 @@ static std::unique_ptr<MappedMemory> MapFile(const char* filename,
}
static void CreateAndWriteCoreJITSnapshot() {
ASSERT((snapshot_kind == kCoreJIT) || (snapshot_kind == kCoreJITAll));
ASSERT(snapshot_kind == kCoreJIT);
ASSERT(vm_snapshot_data_filename != NULL);
ASSERT(vm_snapshot_instructions_filename != NULL);
ASSERT(isolate_snapshot_data_filename != NULL);
@ -909,6 +905,8 @@ static int GenerateSnapshotFromKernel(const uint8_t* kernel_buffer,
Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size));
CHECK_RESULT(result);
MaybeLoadCode();
switch (snapshot_kind) {
case kAppAOTBlobs:
case kAppAOTAssembly: {
@ -927,21 +925,13 @@ static int GenerateSnapshotFromKernel(const uint8_t* kernel_buffer,
case kCore:
CreateAndWriteCoreSnapshot();
break;
case kCoreJITAll:
CompileAll();
CreateAndWriteCoreJITSnapshot();
break;
case kCoreJIT:
LoadBytecode();
LoadCompilationTrace();
CreateAndWriteCoreJITSnapshot();
break;
case kApp:
CreateAndWriteAppSnapshot();
break;
case kAppJIT:
LoadBytecode();
LoadCompilationTrace();
CreateAndWriteAppJITSnapshot();
break;
case kVMAOTAssembly: {
@ -1019,8 +1009,7 @@ int main(int argc, char** argv) {
if (IsSnapshottingForPrecompilation()) {
vm_options.AddArgument("--precompilation");
} else if ((snapshot_kind == kCoreJITAll) || (snapshot_kind == kCoreJIT) ||
(snapshot_kind == kAppJIT)) {
} else if ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT)) {
vm_options.AddArgument("--fields_may_be_reset");
#if !defined(TARGET_ARCH_IA32)
vm_options.AddArgument("--link_natives_lazily");

View file

@ -1576,7 +1576,9 @@ class BytecodeSerializationCluster : public SerializationCluster {
intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawBytecode* bytecode = objects_[i];
s->Write<int32_t>(bytecode->ptr()->instructions_size_);
WriteFromTo(bytecode);
s->Write<int32_t>(bytecode->ptr()->instructions_binary_offset_);
s->Write<int32_t>(bytecode->ptr()->source_positions_binary_offset_);
}
}
@ -1608,10 +1610,25 @@ class BytecodeDeserializationCluster : public DeserializationCluster {
RawBytecode* bytecode = reinterpret_cast<RawBytecode*>(d->Ref(id));
Deserializer::InitializeHeader(bytecode, kBytecodeCid,
Bytecode::InstanceSize(), is_vm_object);
bytecode->ptr()->instructions_ = 0;
bytecode->ptr()->instructions_size_ = d->Read<int32_t>();
ReadFromTo(bytecode);
bytecode->ptr()->instructions_binary_offset_ = d->Read<int32_t>();
bytecode->ptr()->source_positions_binary_offset_ = d->Read<int32_t>();
}
}
void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
Bytecode& bytecode = Bytecode::Handle(zone);
ExternalTypedData& binary = ExternalTypedData::Handle(zone);
for (intptr_t i = start_index_; i < stop_index_; i++) {
bytecode ^= refs.At(i);
binary = bytecode.GetBinary(zone);
bytecode.set_instructions(reinterpret_cast<uword>(
binary.DataAddr(bytecode.instructions_binary_offset())));
}
}
};
class ObjectPoolSerializationCluster : public SerializationCluster {

View file

@ -647,13 +647,8 @@ RawBytecode* BytecodeMetadataHelper::ReadBytecode(const ObjectPool& pool) {
ASSERT(Utils::IsAligned(data, sizeof(KBCInstr)));
helper_->reader_.set_offset(offset + size);
const ExternalTypedData& instructions = ExternalTypedData::Handle(
helper_->zone_,
ExternalTypedData::New(kExternalTypedDataInt8ArrayCid,
const_cast<uint8_t*>(data), size, Heap::kOld));
// Create and return bytecode object.
return Bytecode::New(instructions, pool);
return Bytecode::New(reinterpret_cast<uword>(data), size, offset, pool);
}
void BytecodeMetadataHelper::ReadExceptionsTable(const Bytecode& bytecode,

View file

@ -813,8 +813,7 @@ DART_FORCE_INLINE bool Interpreter::Invoke(Thread* thread,
callee_fp[kKBCSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(*pc);
callee_fp[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP);
pp_ = bytecode->ptr()->object_pool_;
*pc =
reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_->ptr()->data_);
*pc = reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_);
pc_ = reinterpret_cast<uword>(*pc); // For the profiler.
*FP = callee_fp;
fp_ = callee_fp; // For the profiler.
@ -1388,8 +1387,7 @@ RawObject* Interpreter::Call(RawFunction* function,
// Ready to start executing bytecode. Load entry point and corresponding
// object pool.
pc =
reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_->ptr()->data_);
pc = reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_);
pc_ = reinterpret_cast<uword>(pc); // For the profiler.
fp_ = FP; // For the profiler.
pp_ = bytecode->ptr()->object_pool_;

View file

@ -14769,27 +14769,6 @@ RawArray* Code::await_token_positions() const {
#endif
}
void Bytecode::set_instructions(const ExternalTypedData& instructions) const {
#if !defined(DART_PRECOMPILED_RUNTIME)
ASSERT(Thread::Current()->IsMutatorThread());
// The interpreter requires the instructions to be aligned.
ASSERT(Utils::IsAligned(instructions.DataAddr(0), sizeof(KBCInstr)));
StorePointer(&raw_ptr()->instructions_, instructions.raw());
#else
UNREACHABLE();
#endif
}
uword Bytecode::PayloadStart() const {
const ExternalTypedData& instr = ExternalTypedData::Handle(instructions());
return reinterpret_cast<uword>(instr.DataAddr(0));
}
intptr_t Bytecode::Size() const {
const ExternalTypedData& instr = ExternalTypedData::Handle(instructions());
return instr.LengthInBytes();
}
void Bytecode::Disassemble(DisassemblyFormatter* formatter) const {
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
#if !defined(DART_PRECOMPILED_RUNTIME)
@ -14809,7 +14788,9 @@ void Bytecode::Disassemble(DisassemblyFormatter* formatter) const {
}
#if !defined(DART_PRECOMPILED_RUNTIME)
RawBytecode* Bytecode::New(const ExternalTypedData& instructions,
RawBytecode* Bytecode::New(uword instructions,
intptr_t instructions_size,
intptr_t instructions_offset,
const ObjectPool& object_pool) {
ASSERT(Object::bytecode_class() != Class::null());
Bytecode& result = Bytecode::Handle();
@ -14818,9 +14799,11 @@ RawBytecode* Bytecode::New(const ExternalTypedData& instructions,
RawObject* raw = Object::Allocate(Bytecode::kClassId, size, Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
result.set_pc_descriptors(Object::empty_descriptors());
result.set_instructions(instructions);
result.set_instructions_size(instructions_size);
result.set_object_pool(object_pool);
result.set_pc_descriptors(Object::empty_descriptors());
result.set_instructions_binary_offset(instructions_offset);
result.set_source_positions_binary_offset(0);
}
return result.raw();

View file

@ -5220,11 +5220,10 @@ class Code : public Object {
class Bytecode : public Object {
public:
RawExternalTypedData* instructions() const {
return raw_ptr()->instructions_;
}
uword PayloadStart() const;
intptr_t Size() const;
uword instructions() const { return raw_ptr()->instructions_; }
uword PayloadStart() const { return instructions(); }
intptr_t Size() const { return raw_ptr()->instructions_size_; }
RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; }
@ -5265,7 +5264,9 @@ class Bytecode : public Object {
return RoundedAllocationSize(sizeof(RawBytecode));
}
#if !defined(DART_PRECOMPILED_RUNTIME)
static RawBytecode* New(const ExternalTypedData& instructions,
static RawBytecode* New(uword instructions,
intptr_t instructions_size,
intptr_t instructions_offset,
const ObjectPool& object_pool);
#endif
@ -5273,6 +5274,13 @@ class Bytecode : public Object {
TokenPosition GetTokenIndexOfPC(uword pc) const;
intptr_t instructions_binary_offset() const {
return raw_ptr()->instructions_binary_offset_;
}
void set_instructions_binary_offset(intptr_t value) const {
StoreNonPointer(&raw_ptr()->instructions_binary_offset_, value);
}
intptr_t source_positions_binary_offset() const {
return raw_ptr()->source_positions_binary_offset_;
}
@ -5303,15 +5311,22 @@ class Bytecode : public Object {
static RawBytecode* FindCode(uword pc);
private:
void set_instructions(uword instructions) const {
// The interpreter requires the instructions to be aligned.
ASSERT(Utils::IsAligned(instructions, sizeof(uint32_t)));
StoreNonPointer(&raw_ptr()->instructions_, instructions);
}
void set_instructions_size(intptr_t size) const {
StoreNonPointer(&raw_ptr()->instructions_size_, size);
}
void set_object_pool(const ObjectPool& object_pool) const {
StorePointer(&raw_ptr()->object_pool_, object_pool.raw());
}
friend class BytecodeDeserializationCluster;
friend class RawObject; // For RawObject::SizeFromClass().
friend class RawBytecode;
void set_instructions(const ExternalTypedData& instructions) const;
FINAL_HEAP_OBJECT_IMPLEMENTATION(Bytecode, Object);
friend class Class;
friend class SnapshotWriter;

View file

@ -115,6 +115,7 @@ void ProgramVisitor::VisitFunctions(FunctionVisitor* visitor) {
}
}
#if !defined(DART_PRECOMPILED_RUNTIME)
void ProgramVisitor::BindStaticCalls() {
#if !defined(TARGET_ARCH_DBC)
if (FLAG_precompiled_mode) {
@ -308,6 +309,7 @@ void ProgramVisitor::DedupPcDescriptors() {
explicit DedupPcDescriptorsVisitor(Zone* zone)
: zone_(zone),
canonical_pc_descriptors_(),
bytecode_(Bytecode::Handle(zone)),
code_(Code::Handle(zone)),
pc_descriptor_(PcDescriptors::Handle(zone)) {}
@ -317,6 +319,14 @@ void ProgramVisitor::DedupPcDescriptors() {
}
void Visit(const Function& function) {
bytecode_ = function.bytecode();
if (!bytecode_.IsNull()) {
pc_descriptor_ = bytecode_.pc_descriptors();
if (!pc_descriptor_.IsNull()) {
pc_descriptor_ = DedupPcDescriptor(pc_descriptor_);
bytecode_.set_pc_descriptors(pc_descriptor_);
}
}
if (!function.HasCode()) {
return;
}
@ -341,6 +351,7 @@ void ProgramVisitor::DedupPcDescriptors() {
private:
Zone* zone_;
PcDescriptorsSet canonical_pc_descriptors_;
Bytecode& bytecode_;
Code& code_;
PcDescriptors& pc_descriptor_;
};
@ -380,7 +391,6 @@ class TypedDataKeyValueTrait {
typedef DirectChainedHashMap<TypedDataKeyValueTrait> TypedDataSet;
#if !defined(DART_PRECOMPILED_RUNTIME)
void ProgramVisitor::DedupDeoptEntries() {
class DedupDeoptEntriesVisitor : public FunctionVisitor {
public:
@ -437,7 +447,6 @@ void ProgramVisitor::DedupDeoptEntries() {
DedupDeoptEntriesVisitor visitor(Thread::Current()->zone());
ProgramVisitor::VisitFunctions(&visitor);
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
#if defined(DART_PRECOMPILER)
void ProgramVisitor::DedupCatchEntryMovesMaps() {
@ -876,8 +885,10 @@ void ProgramVisitor::DedupInstructionsWithSameMetadata() {
ProgramVisitor::VisitFunctions(&visitor);
#endif // defined(DART_PRECOMPILER)
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
void ProgramVisitor::Dedup() {
#if !defined(DART_PRECOMPILED_RUNTIME)
Thread* thread = Thread::Current();
StackZone stack_zone(thread);
HANDLESCOPE(thread);
@ -901,6 +912,7 @@ void ProgramVisitor::Dedup() {
DedupInstructions();
}
#endif
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
} // namespace dart

View file

@ -30,11 +30,12 @@ class ProgramVisitor : public AllStatic {
static void Dedup();
private:
#if !defined(DART_PRECOMPILED_RUNTIME)
static void BindStaticCalls();
static void ShareMegamorphicBuckets();
static void DedupStackMaps();
static void DedupPcDescriptors();
NOT_IN_PRECOMPILED(static void DedupDeoptEntries());
static void DedupDeoptEntries();
#if defined(DART_PRECOMPILER)
static void DedupCatchEntryMovesMaps();
#endif
@ -42,6 +43,7 @@ class ProgramVisitor : public AllStatic {
static void DedupLists();
static void DedupInstructions();
static void DedupInstructionsWithSameMetadata();
#endif // !defined(DART_PRECOMPILED_RUNTIME)
};
} // namespace dart

View file

@ -556,9 +556,8 @@ intptr_t RawCode::VisitCodePointers(RawCode* raw_obj,
bool RawBytecode::ContainsPC(RawObject* raw_obj, uword pc) {
if (raw_obj->IsBytecode()) {
RawBytecode* raw_bytecode = static_cast<RawBytecode*>(raw_obj);
RawExternalTypedData* bytes = raw_bytecode->ptr()->instructions_;
uword start = reinterpret_cast<uword>(bytes->ptr()->data_);
uword size = Smi::Value(bytes->ptr()->length_);
uword start = raw_bytecode->ptr()->instructions_;
uword size = raw_bytecode->ptr()->instructions_size_;
return (pc - start) < size;
}
return false;

View file

@ -1314,16 +1314,19 @@ class RawCode : public RawObject {
class RawBytecode : public RawObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(Bytecode);
uword instructions_;
intptr_t instructions_size_;
VISIT_FROM(RawObject*, object_pool_);
RawObjectPool* object_pool_;
RawExternalTypedData* instructions_;
RawFunction* function_;
RawExceptionHandlers* exception_handlers_;
RawPcDescriptors* pc_descriptors_;
VISIT_TO(RawObject*, pc_descriptors_);
RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
intptr_t source_positions_binary_offset_;
int32_t instructions_binary_offset_;
int32_t source_positions_binary_offset_;
static bool ContainsPC(RawObject* raw_obj, uword pc);