mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +00:00
[vm, compiler] Fix annotating pool references in gen_snapshot.
This was broken by the move to the global object pool. TEST=--disassemble Change-Id: I2cbff1e2fa1a56d8d4d98d447a5726c0764e1a0e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244460 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
47db18a2da
commit
f7c7076fe8
41
runtime/vm/instructions.cc
Normal file
41
runtime/vm/instructions.cc
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright (c) 2022, 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.
|
||||||
|
|
||||||
|
#include "vm/instructions.h"
|
||||||
|
|
||||||
|
#include "vm/object.h"
|
||||||
|
#if defined(DART_PRECOMPILER)
|
||||||
|
#include "vm/compiler/aot/precompiler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace dart {
|
||||||
|
|
||||||
|
bool ObjectAtPoolIndex(const Code& code, intptr_t index, Object* obj) {
|
||||||
|
#if defined(DART_PRECOMPILER)
|
||||||
|
if (FLAG_precompiled_mode) {
|
||||||
|
Precompiler* precompiler = Precompiler::Instance();
|
||||||
|
if (precompiler != nullptr) {
|
||||||
|
compiler::ObjectPoolBuilder* pool =
|
||||||
|
precompiler->global_object_pool_builder();
|
||||||
|
if (index < pool->CurrentLength()) {
|
||||||
|
compiler::ObjectPoolBuilderEntry& entry = pool->EntryAt(index);
|
||||||
|
if (entry.type() == compiler::ObjectPoolBuilderEntry::kTaggedObject) {
|
||||||
|
*obj = entry.obj_->ptr();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
|
||||||
|
if (!pool.IsNull() && (index < pool.Length()) &&
|
||||||
|
(pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
|
||||||
|
*obj = pool.ObjectAt(index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dart
|
|
@ -26,6 +26,7 @@ namespace dart {
|
||||||
class Object;
|
class Object;
|
||||||
class Code;
|
class Code;
|
||||||
|
|
||||||
|
bool ObjectAtPoolIndex(const Code& code, intptr_t index, Object* obj);
|
||||||
bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj);
|
bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj);
|
||||||
|
|
||||||
#if !defined(TARGET_ARCH_IA32)
|
#if !defined(TARGET_ARCH_IA32)
|
||||||
|
|
|
@ -197,12 +197,7 @@ bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
|
||||||
Register dst;
|
Register dst;
|
||||||
if (IsLoadWithOffset(instr, PP, &offset, &dst)) {
|
if (IsLoadWithOffset(instr, PP, &offset, &dst)) {
|
||||||
intptr_t index = ObjectPool::IndexFromOffset(offset);
|
intptr_t index = ObjectPool::IndexFromOffset(offset);
|
||||||
const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
|
return ObjectAtPoolIndex(code, index, obj);
|
||||||
if (!pool.IsNull() && (index < pool.Length()) &&
|
|
||||||
(pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
|
|
||||||
*obj = pool.ObjectAt(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (IsLoadWithOffset(instr, THR, &offset, &dst)) {
|
} else if (IsLoadWithOffset(instr, THR, &offset, &dst)) {
|
||||||
return Thread::ObjectAtOffset(offset, obj);
|
return Thread::ObjectAtOffset(offset, obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -304,17 +304,27 @@ bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
|
||||||
// PP is untagged on ARM64.
|
// PP is untagged on ARM64.
|
||||||
ASSERT(Utils::IsAligned(offset, 8));
|
ASSERT(Utils::IsAligned(offset, 8));
|
||||||
intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
|
intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
|
||||||
const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
|
return ObjectAtPoolIndex(code, index, obj);
|
||||||
if (!pool.IsNull() && (index < pool.Length()) &&
|
|
||||||
(pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
|
|
||||||
*obj = pool.ObjectAt(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (instr->RnField() == THR) {
|
} else if (instr->RnField() == THR) {
|
||||||
return Thread::ObjectAtOffset(offset, obj);
|
return Thread::ObjectAtOffset(offset, obj);
|
||||||
}
|
}
|
||||||
|
if (instr->RnField() == instr->RtField()) {
|
||||||
|
Instr* add = Instr::At(pc - Instr::kInstrSize);
|
||||||
|
if (add->IsAddSubImmOp() && add->SFField() && (instr->Bit(22) == 1) &&
|
||||||
|
(add->RdField() == add->RtField())) {
|
||||||
|
offset = (add->Imm12Field() << 12) + offset;
|
||||||
|
if (add->RnField() == PP) {
|
||||||
|
// PP is untagged on ARM64.
|
||||||
|
ASSERT(Utils::IsAligned(offset, 8));
|
||||||
|
intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
|
||||||
|
return ObjectAtPoolIndex(code, index, obj);
|
||||||
|
} else if (add->RnField() == THR) {
|
||||||
|
return Thread::ObjectAtOffset(offset, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO(rmacnak): Loads with offsets beyond 24 bits.
|
||||||
}
|
}
|
||||||
// TODO(rmacnak): Loads with offsets beyond 12 bits.
|
|
||||||
|
|
||||||
if (instr->IsAddSubImmOp() && instr->SFField() &&
|
if (instr->IsAddSubImmOp() && instr->SFField() &&
|
||||||
(instr->RnField() == NULL_REG)) {
|
(instr->RnField() == NULL_REG)) {
|
||||||
|
|
|
@ -231,12 +231,7 @@ bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
|
||||||
return false; // Being used as argument register A5.
|
return false; // Being used as argument register A5.
|
||||||
}
|
}
|
||||||
intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
|
intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
|
||||||
const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
|
return ObjectAtPoolIndex(code, index, obj);
|
||||||
if (!pool.IsNull() && (index < pool.Length()) &&
|
|
||||||
(pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
|
|
||||||
*obj = pool.ObjectAt(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (instr.rs1p() == THR) {
|
} else if (instr.rs1p() == THR) {
|
||||||
return Thread::ObjectAtOffset(offset, obj);
|
return Thread::ObjectAtOffset(offset, obj);
|
||||||
}
|
}
|
||||||
|
@ -255,12 +250,7 @@ bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
|
||||||
return false; // Being used as argument register A5.
|
return false; // Being used as argument register A5.
|
||||||
}
|
}
|
||||||
intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
|
intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
|
||||||
const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
|
return ObjectAtPoolIndex(code, index, obj);
|
||||||
if (!pool.IsNull() && (index < pool.Length()) &&
|
|
||||||
(pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
|
|
||||||
*obj = pool.ObjectAt(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (instr.rs1() == THR) {
|
} else if (instr.rs1() == THR) {
|
||||||
return Thread::ObjectAtOffset(offset, obj);
|
return Thread::ObjectAtOffset(offset, obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,21 +59,11 @@ bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
|
||||||
if ((bytes[1] == 0x8b) || (bytes[1] == 0x3b)) { // movq, cmpq
|
if ((bytes[1] == 0x8b) || (bytes[1] == 0x3b)) { // movq, cmpq
|
||||||
if ((bytes[2] & 0xc7) == (0x80 | (PP & 7))) { // [r15+disp32]
|
if ((bytes[2] & 0xc7) == (0x80 | (PP & 7))) { // [r15+disp32]
|
||||||
intptr_t index = IndexFromPPLoadDisp32(pc + 3);
|
intptr_t index = IndexFromPPLoadDisp32(pc + 3);
|
||||||
const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
|
return ObjectAtPoolIndex(code, index, obj);
|
||||||
if (!pool.IsNull() && (index < pool.Length()) &&
|
|
||||||
(pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
|
|
||||||
*obj = pool.ObjectAt(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((bytes[2] & 0xc7) == (0x40 | (PP & 7))) { // [r15+disp8]
|
if ((bytes[2] & 0xc7) == (0x40 | (PP & 7))) { // [r15+disp8]
|
||||||
intptr_t index = IndexFromPPLoadDisp8(pc + 3);
|
intptr_t index = IndexFromPPLoadDisp8(pc + 3);
|
||||||
const ObjectPool& pool = ObjectPool::Handle(code.GetObjectPool());
|
return ObjectAtPoolIndex(code, index, obj);
|
||||||
if (!pool.IsNull() && (index < pool.Length()) &&
|
|
||||||
(pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject)) {
|
|
||||||
*obj = pool.ObjectAt(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@ vm_sources = [
|
||||||
"hash_table.h",
|
"hash_table.h",
|
||||||
"image_snapshot.cc",
|
"image_snapshot.cc",
|
||||||
"image_snapshot.h",
|
"image_snapshot.h",
|
||||||
|
"instructions.cc",
|
||||||
"instructions.h",
|
"instructions.h",
|
||||||
"instructions_arm.cc",
|
"instructions_arm.cc",
|
||||||
"instructions_arm.h",
|
"instructions_arm.h",
|
||||||
|
|
Loading…
Reference in a new issue