[VM] Add "patchability" bit to ObjectPool objects
This allows initializing a new pool from an old pool while preserving the patchability bit. Issue https://github.com/dart-lang/sdk/issues/33274 Change-Id: I369bb852aea8e183da2fbf7ca3571312dc5fda27 Reviewed-on: https://dart-review.googlesource.com/71162 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
4c2169e63f
commit
5d7ca9cd1e
@@ -1860,10 +1860,9 @@ class ObjectPoolSerializationCluster : public SerializationCluster {
|
||||
objects_.Add(pool);
|
||||
|
||||
intptr_t length = pool->ptr()->length_;
|
||||
uint8_t* entry_types = pool->ptr()->entry_types();
|
||||
uint8_t* entry_bits = pool->ptr()->entry_bits();
|
||||
for (intptr_t i = 0; i < length; i++) {
|
||||
ObjectPool::EntryType entry_type =
|
||||
static_cast<ObjectPool::EntryType>(entry_types[i]);
|
||||
auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]);
|
||||
if (entry_type == ObjectPool::kTaggedObject) {
|
||||
s->Push(pool->ptr()->data()[i].raw_obj_);
|
||||
}
|
||||
@@ -1888,13 +1887,11 @@ class ObjectPoolSerializationCluster : public SerializationCluster {
|
||||
RawObjectPool* pool = objects_[i];
|
||||
intptr_t length = pool->ptr()->length_;
|
||||
s->WriteUnsigned(length);
|
||||
uint8_t* entry_types = pool->ptr()->entry_types();
|
||||
uint8_t* entry_bits = pool->ptr()->entry_bits();
|
||||
for (intptr_t j = 0; j < length; j++) {
|
||||
ObjectPool::EntryType entry_type =
|
||||
static_cast<ObjectPool::EntryType>(entry_types[j]);
|
||||
s->Write<int8_t>(entry_type);
|
||||
s->Write<uint8_t>(entry_bits[j]);
|
||||
RawObjectPool::Entry& entry = pool->ptr()->data()[j];
|
||||
switch (entry_type) {
|
||||
switch (ObjectPool::TypeBits::decode(entry_bits[j])) {
|
||||
case ObjectPool::kTaggedObject: {
|
||||
#if !defined(TARGET_ARCH_DBC)
|
||||
if ((entry.raw_obj_ ==
|
||||
@@ -1958,11 +1955,10 @@ class ObjectPoolDeserializationCluster : public DeserializationCluster {
|
||||
pool, kObjectPoolCid, ObjectPool::InstanceSize(length), is_vm_object);
|
||||
pool->ptr()->length_ = length;
|
||||
for (intptr_t j = 0; j < length; j++) {
|
||||
ObjectPool::EntryType entry_type =
|
||||
static_cast<ObjectPool::EntryType>(d->Read<int8_t>());
|
||||
pool->ptr()->entry_types()[j] = entry_type;
|
||||
const uint8_t entry_bits = d->Read<uint8_t>();
|
||||
pool->ptr()->entry_bits()[j] = entry_bits;
|
||||
RawObjectPool::Entry& entry = pool->ptr()->data()[j];
|
||||
switch (entry_type) {
|
||||
switch (ObjectPool::TypeBits::decode(entry_bits)) {
|
||||
case ObjectPool::kTaggedObject:
|
||||
entry.raw_obj_ = d->ReadRef();
|
||||
break;
|
||||
|
||||
@@ -228,24 +228,23 @@ const Code::Comments& Assembler::GetCodeComments() const {
|
||||
}
|
||||
|
||||
intptr_t ObjectPoolWrapper::AddObject(const Object& obj,
|
||||
Patchability patchable) {
|
||||
ObjectPool::Patchability patchable) {
|
||||
ASSERT(obj.IsNotTemporaryScopedHandle());
|
||||
return AddObject(ObjectPoolWrapperEntry(&obj), patchable);
|
||||
return AddObject(ObjectPoolWrapperEntry(&obj, patchable));
|
||||
}
|
||||
|
||||
intptr_t ObjectPoolWrapper::AddImmediate(uword imm) {
|
||||
return AddObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate),
|
||||
kNotPatchable);
|
||||
return AddObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate,
|
||||
ObjectPool::kNotPatchable));
|
||||
}
|
||||
|
||||
intptr_t ObjectPoolWrapper::AddObject(ObjectPoolWrapperEntry entry,
|
||||
Patchability patchable) {
|
||||
ASSERT((entry.type_ != ObjectPool::kTaggedObject) ||
|
||||
intptr_t ObjectPoolWrapper::AddObject(ObjectPoolWrapperEntry entry) {
|
||||
ASSERT((entry.type() != ObjectPool::kTaggedObject) ||
|
||||
(entry.obj_->IsNotTemporaryScopedHandle() &&
|
||||
(entry.equivalence_ == NULL ||
|
||||
entry.equivalence_->IsNotTemporaryScopedHandle())));
|
||||
object_pool_.Add(entry);
|
||||
if (patchable == kNotPatchable) {
|
||||
if (entry.patchable() == ObjectPool::kNotPatchable) {
|
||||
// The object isn't patchable. Record the index for fast lookup.
|
||||
object_pool_index_table_.Insert(
|
||||
ObjIndexPair(entry, object_pool_.length() - 1));
|
||||
@@ -253,47 +252,46 @@ intptr_t ObjectPoolWrapper::AddObject(ObjectPoolWrapperEntry entry,
|
||||
return object_pool_.length() - 1;
|
||||
}
|
||||
|
||||
intptr_t ObjectPoolWrapper::FindObject(ObjectPoolWrapperEntry entry,
|
||||
Patchability patchable) {
|
||||
intptr_t ObjectPoolWrapper::FindObject(ObjectPoolWrapperEntry entry) {
|
||||
// If the object is not patchable, check if we've already got it in the
|
||||
// object pool.
|
||||
if (patchable == kNotPatchable) {
|
||||
if (entry.patchable() == ObjectPool::kNotPatchable) {
|
||||
intptr_t idx = object_pool_index_table_.LookupValue(entry);
|
||||
if (idx != ObjIndexPair::kNoIndex) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
return AddObject(entry, patchable);
|
||||
return AddObject(entry);
|
||||
}
|
||||
|
||||
intptr_t ObjectPoolWrapper::FindObject(const Object& obj,
|
||||
Patchability patchable) {
|
||||
return FindObject(ObjectPoolWrapperEntry(&obj), patchable);
|
||||
ObjectPool::Patchability patchable) {
|
||||
return FindObject(ObjectPoolWrapperEntry(&obj, patchable));
|
||||
}
|
||||
|
||||
intptr_t ObjectPoolWrapper::FindObject(const Object& obj,
|
||||
const Object& equivalence) {
|
||||
return FindObject(ObjectPoolWrapperEntry(&obj, &equivalence), kNotPatchable);
|
||||
return FindObject(
|
||||
ObjectPoolWrapperEntry(&obj, &equivalence, ObjectPool::kNotPatchable));
|
||||
}
|
||||
|
||||
intptr_t ObjectPoolWrapper::FindImmediate(uword imm) {
|
||||
return FindObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate),
|
||||
kNotPatchable);
|
||||
return FindObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate,
|
||||
ObjectPool::kNotPatchable));
|
||||
}
|
||||
|
||||
intptr_t ObjectPoolWrapper::FindNativeFunction(const ExternalLabel* label,
|
||||
Patchability patchable) {
|
||||
return FindObject(
|
||||
ObjectPoolWrapperEntry(label->address(), ObjectPool::kNativeFunction),
|
||||
patchable);
|
||||
intptr_t ObjectPoolWrapper::FindNativeFunction(
|
||||
const ExternalLabel* label,
|
||||
ObjectPool::Patchability patchable) {
|
||||
return FindObject(ObjectPoolWrapperEntry(
|
||||
label->address(), ObjectPool::kNativeFunction, patchable));
|
||||
}
|
||||
|
||||
intptr_t ObjectPoolWrapper::FindNativeFunctionWrapper(
|
||||
const ExternalLabel* label,
|
||||
Patchability patchable) {
|
||||
return FindObject(ObjectPoolWrapperEntry(label->address(),
|
||||
ObjectPool::kNativeFunctionWrapper),
|
||||
patchable);
|
||||
ObjectPool::Patchability patchable) {
|
||||
return FindObject(ObjectPoolWrapperEntry(
|
||||
label->address(), ObjectPool::kNativeFunctionWrapper, patchable));
|
||||
}
|
||||
|
||||
RawObjectPool* ObjectPoolWrapper::MakeObjectPool() {
|
||||
@@ -303,8 +301,9 @@ RawObjectPool* ObjectPoolWrapper::MakeObjectPool() {
|
||||
}
|
||||
const ObjectPool& result = ObjectPool::Handle(ObjectPool::New(len));
|
||||
for (intptr_t i = 0; i < len; ++i) {
|
||||
ObjectPool::EntryType type = object_pool_[i].type_;
|
||||
result.SetTypeAt(i, type);
|
||||
auto type = object_pool_[i].type();
|
||||
auto patchable = object_pool_[i].patchable();
|
||||
result.SetTypeAt(i, type, patchable);
|
||||
if (type == ObjectPool::kTaggedObject) {
|
||||
result.SetObjectAt(i, *object_pool_[i].obj_);
|
||||
} else {
|
||||
|
||||
@@ -285,19 +285,40 @@ class AssemblerBuffer : public ValueObject {
|
||||
};
|
||||
|
||||
struct ObjectPoolWrapperEntry {
|
||||
ObjectPoolWrapperEntry() : raw_value_(), type_(), equivalence_() {}
|
||||
explicit ObjectPoolWrapperEntry(const Object* obj)
|
||||
: obj_(obj), type_(ObjectPool::kTaggedObject), equivalence_(obj) {}
|
||||
explicit ObjectPoolWrapperEntry(const Object* obj, const Object* eqv)
|
||||
: obj_(obj), type_(ObjectPool::kTaggedObject), equivalence_(eqv) {}
|
||||
ObjectPoolWrapperEntry(uword value, ObjectPool::EntryType info)
|
||||
: raw_value_(value), type_(info), equivalence_() {}
|
||||
ObjectPoolWrapperEntry() : raw_value_(), entry_bits_(0), equivalence_() {}
|
||||
ObjectPoolWrapperEntry(const Object* obj, ObjectPool::Patchability patchable)
|
||||
: obj_(obj),
|
||||
entry_bits_(ObjectPool::TypeBits::encode(ObjectPool::kTaggedObject) |
|
||||
ObjectPool::PatchableBit::encode(patchable)),
|
||||
equivalence_(obj) {}
|
||||
ObjectPoolWrapperEntry(const Object* obj,
|
||||
const Object* eqv,
|
||||
ObjectPool::Patchability patchable)
|
||||
: obj_(obj),
|
||||
entry_bits_(ObjectPool::TypeBits::encode(ObjectPool::kTaggedObject) |
|
||||
ObjectPool::PatchableBit::encode(patchable)),
|
||||
equivalence_(eqv) {}
|
||||
ObjectPoolWrapperEntry(uword value,
|
||||
ObjectPool::EntryType info,
|
||||
ObjectPool::Patchability patchable)
|
||||
: raw_value_(value),
|
||||
entry_bits_(ObjectPool::TypeBits::encode(info) |
|
||||
ObjectPool::PatchableBit::encode(patchable)),
|
||||
equivalence_() {}
|
||||
|
||||
ObjectPool::EntryType type() const {
|
||||
return ObjectPool::TypeBits::decode(entry_bits_);
|
||||
}
|
||||
|
||||
ObjectPool::Patchability patchable() const {
|
||||
return ObjectPool::PatchableBit::decode(entry_bits_);
|
||||
}
|
||||
|
||||
union {
|
||||
const Object* obj_;
|
||||
uword raw_value_;
|
||||
};
|
||||
ObjectPool::EntryType type_;
|
||||
uint8_t entry_bits_;
|
||||
const Object* equivalence_;
|
||||
};
|
||||
|
||||
@@ -312,12 +333,14 @@ class ObjIndexPair {
|
||||
static const intptr_t kNoIndex = -1;
|
||||
|
||||
ObjIndexPair()
|
||||
: key_(static_cast<uword>(NULL), ObjectPool::kTaggedObject),
|
||||
: key_(static_cast<uword>(NULL),
|
||||
ObjectPool::kTaggedObject,
|
||||
ObjectPool::kPatchable),
|
||||
value_(kNoIndex) {}
|
||||
|
||||
ObjIndexPair(Key key, Value value) : value_(value) {
|
||||
key_.type_ = key.type_;
|
||||
if (key.type_ == ObjectPool::kTaggedObject) {
|
||||
key_.entry_bits_ = key.entry_bits_;
|
||||
if (key.type() == ObjectPool::kTaggedObject) {
|
||||
key_.obj_ = key.obj_;
|
||||
key_.equivalence_ = key.equivalence_;
|
||||
} else {
|
||||
@@ -330,7 +353,7 @@ class ObjIndexPair {
|
||||
static Value ValueOf(Pair kv) { return kv.value_; }
|
||||
|
||||
static intptr_t Hashcode(Key key) {
|
||||
if (key.type_ != ObjectPool::kTaggedObject) {
|
||||
if (key.type() != ObjectPool::kTaggedObject) {
|
||||
return key.raw_value_;
|
||||
}
|
||||
if (key.obj_->IsSmi()) {
|
||||
@@ -345,8 +368,8 @@ class ObjIndexPair {
|
||||
}
|
||||
|
||||
static inline bool IsKeyEqual(Pair kv, Key key) {
|
||||
if (kv.key_.type_ != key.type_) return false;
|
||||
if (kv.key_.type_ == ObjectPool::kTaggedObject) {
|
||||
if (kv.key_.entry_bits_ != key.entry_bits_) return false;
|
||||
if (kv.key_.type() == ObjectPool::kTaggedObject) {
|
||||
return (kv.key_.obj_->raw() == key.obj_->raw()) &&
|
||||
(kv.key_.equivalence_->raw() == key.equivalence_->raw());
|
||||
}
|
||||
@@ -358,30 +381,27 @@ class ObjIndexPair {
|
||||
Value value_;
|
||||
};
|
||||
|
||||
enum Patchability {
|
||||
kPatchable,
|
||||
kNotPatchable,
|
||||
};
|
||||
|
||||
class ObjectPoolWrapper : public ValueObject {
|
||||
public:
|
||||
intptr_t AddObject(const Object& obj, Patchability patchable = kNotPatchable);
|
||||
intptr_t AddObject(
|
||||
const Object& obj,
|
||||
ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
|
||||
intptr_t AddImmediate(uword imm);
|
||||
|
||||
intptr_t FindObject(const Object& obj,
|
||||
Patchability patchable = kNotPatchable);
|
||||
intptr_t FindObject(
|
||||
const Object& obj,
|
||||
ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
|
||||
intptr_t FindObject(const Object& obj, const Object& equivalence);
|
||||
intptr_t FindImmediate(uword imm);
|
||||
intptr_t FindNativeFunction(const ExternalLabel* label,
|
||||
Patchability patchable);
|
||||
ObjectPool::Patchability patchable);
|
||||
intptr_t FindNativeFunctionWrapper(const ExternalLabel* label,
|
||||
Patchability patchable);
|
||||
ObjectPool::Patchability patchable);
|
||||
|
||||
RawObjectPool* MakeObjectPool();
|
||||
|
||||
private:
|
||||
intptr_t AddObject(ObjectPoolWrapperEntry entry, Patchability patchable);
|
||||
intptr_t FindObject(ObjectPoolWrapperEntry entry, Patchability patchable);
|
||||
intptr_t AddObject(ObjectPoolWrapperEntry entry);
|
||||
intptr_t FindObject(ObjectPoolWrapperEntry entry);
|
||||
|
||||
// Objects and jump targets.
|
||||
GrowableArray<ObjectPoolWrapperEntry> object_pool_;
|
||||
|
||||
@@ -1508,7 +1508,7 @@ void Assembler::LoadFunctionFromCalleePool(Register dst,
|
||||
|
||||
void Assembler::LoadNativeEntry(Register rd,
|
||||
const ExternalLabel* label,
|
||||
Patchability patchable,
|
||||
ObjectPool::Patchability patchable,
|
||||
Condition cond) {
|
||||
const int32_t offset = ObjectPool::element_offset(
|
||||
object_pool_wrapper_.FindNativeFunction(label, patchable));
|
||||
@@ -2449,7 +2449,7 @@ void Assembler::Vdivqs(QRegister qd, QRegister qn, QRegister qm) {
|
||||
}
|
||||
|
||||
void Assembler::Branch(const StubEntry& stub_entry,
|
||||
Patchability patchable,
|
||||
ObjectPool::Patchability patchable,
|
||||
Register pp,
|
||||
Condition cond) {
|
||||
const Code& target_code = Code::ZoneHandle(stub_entry.code());
|
||||
@@ -2461,7 +2461,7 @@ void Assembler::Branch(const StubEntry& stub_entry,
|
||||
}
|
||||
|
||||
void Assembler::BranchLink(const Code& target,
|
||||
Patchability patchable,
|
||||
ObjectPool::Patchability patchable,
|
||||
Code::EntryKind entry_kind) {
|
||||
// Make sure that class CallPattern is able to patch the label referred
|
||||
// to by this code sequence.
|
||||
@@ -2475,14 +2475,14 @@ void Assembler::BranchLink(const Code& target,
|
||||
}
|
||||
|
||||
void Assembler::BranchLink(const StubEntry& stub_entry,
|
||||
Patchability patchable) {
|
||||
ObjectPool::Patchability patchable) {
|
||||
const Code& code = Code::ZoneHandle(stub_entry.code());
|
||||
BranchLink(code, patchable);
|
||||
}
|
||||
|
||||
void Assembler::BranchLinkPatchable(const Code& target,
|
||||
Code::EntryKind entry_kind) {
|
||||
BranchLink(target, kPatchable, entry_kind);
|
||||
BranchLink(target, ObjectPool::kPatchable, entry_kind);
|
||||
}
|
||||
|
||||
void Assembler::BranchLinkToRuntime() {
|
||||
|
||||
@@ -690,14 +690,15 @@ class Assembler : public ValueObject {
|
||||
void blx(Register rm, Condition cond = AL);
|
||||
|
||||
void Branch(const StubEntry& stub_entry,
|
||||
Patchability patchable = kNotPatchable,
|
||||
ObjectPool::Patchability patchable = ObjectPool::kNotPatchable,
|
||||
Register pp = PP,
|
||||
Condition cond = AL);
|
||||
|
||||
void BranchLink(const StubEntry& stub_entry,
|
||||
Patchability patchable = kNotPatchable);
|
||||
void BranchLink(
|
||||
const StubEntry& stub_entry,
|
||||
ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
|
||||
void BranchLink(const Code& code,
|
||||
Patchability patchable,
|
||||
ObjectPool::Patchability patchable,
|
||||
Code::EntryKind entry_kind = Code::EntryKind::kNormal);
|
||||
void BranchLinkToRuntime();
|
||||
|
||||
@@ -793,7 +794,7 @@ class Assembler : public ValueObject {
|
||||
Register new_pp);
|
||||
void LoadNativeEntry(Register dst,
|
||||
const ExternalLabel* label,
|
||||
Patchability patchable,
|
||||
ObjectPool::Patchability patchable,
|
||||
Condition cond = AL);
|
||||
void PushObject(const Object& object);
|
||||
void CompareObject(Register rn, const Object& object);
|
||||
|
||||
@@ -433,7 +433,7 @@ bool Assembler::CanLoadFromObjectPool(const Object& object) const {
|
||||
|
||||
void Assembler::LoadNativeEntry(Register dst,
|
||||
const ExternalLabel* label,
|
||||
Patchability patchable) {
|
||||
ObjectPool::Patchability patchable) {
|
||||
const int32_t offset = ObjectPool::element_offset(
|
||||
object_pool_wrapper_.FindNativeFunction(label, patchable));
|
||||
LoadWordFromPoolOffset(dst, offset);
|
||||
@@ -615,7 +615,7 @@ void Assembler::LoadDImmediate(VRegister vd, double immd) {
|
||||
|
||||
void Assembler::Branch(const StubEntry& stub_entry,
|
||||
Register pp,
|
||||
Patchability patchable) {
|
||||
ObjectPool::Patchability patchable) {
|
||||
const Code& target = Code::ZoneHandle(stub_entry.code());
|
||||
const int32_t offset = ObjectPool::element_offset(
|
||||
object_pool_wrapper_.FindObject(target, patchable));
|
||||
@@ -625,11 +625,11 @@ void Assembler::Branch(const StubEntry& stub_entry,
|
||||
}
|
||||
|
||||
void Assembler::BranchPatchable(const StubEntry& stub_entry) {
|
||||
Branch(stub_entry, PP, kPatchable);
|
||||
Branch(stub_entry, PP, ObjectPool::kPatchable);
|
||||
}
|
||||
|
||||
void Assembler::BranchLink(const StubEntry& stub_entry,
|
||||
Patchability patchable) {
|
||||
ObjectPool::Patchability patchable) {
|
||||
const Code& target = Code::ZoneHandle(stub_entry.code());
|
||||
const int32_t offset = ObjectPool::element_offset(
|
||||
object_pool_wrapper_.FindObject(target, patchable));
|
||||
@@ -639,7 +639,7 @@ void Assembler::BranchLink(const StubEntry& stub_entry,
|
||||
}
|
||||
|
||||
void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) {
|
||||
BranchLink(stub_entry, kPatchable);
|
||||
BranchLink(stub_entry, ObjectPool::kPatchable);
|
||||
}
|
||||
|
||||
void Assembler::BranchLinkToRuntime() {
|
||||
|
||||
@@ -1374,11 +1374,12 @@ class Assembler : public ValueObject {
|
||||
|
||||
void Branch(const StubEntry& stub_entry,
|
||||
Register pp,
|
||||
Patchability patchable = kNotPatchable);
|
||||
ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
|
||||
void BranchPatchable(const StubEntry& stub_entry);
|
||||
|
||||
void BranchLink(const StubEntry& stub_entry,
|
||||
Patchability patchable = kNotPatchable);
|
||||
void BranchLink(
|
||||
const StubEntry& stub_entry,
|
||||
ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
|
||||
|
||||
void BranchLinkPatchable(const StubEntry& stub_entry);
|
||||
void BranchLinkToRuntime();
|
||||
@@ -1490,7 +1491,7 @@ class Assembler : public ValueObject {
|
||||
bool CanLoadFromObjectPool(const Object& object) const;
|
||||
void LoadNativeEntry(Register dst,
|
||||
const ExternalLabel* label,
|
||||
Patchability patchable);
|
||||
ObjectPool::Patchability patchable);
|
||||
void LoadFunctionFromCalleePool(Register dst,
|
||||
const Function& function,
|
||||
Register new_pp);
|
||||
|
||||
@@ -45,7 +45,7 @@ void Assembler::call(Label* label) {
|
||||
|
||||
void Assembler::LoadNativeEntry(Register dst,
|
||||
const ExternalLabel* label,
|
||||
Patchability patchable) {
|
||||
ObjectPool::Patchability patchable) {
|
||||
const int32_t offset = ObjectPool::element_offset(
|
||||
object_pool_wrapper_.FindNativeFunction(label, patchable));
|
||||
LoadWordFromPoolOffset(dst, offset - kHeapObjectTag);
|
||||
@@ -66,7 +66,8 @@ void Assembler::CallPatchable(const StubEntry& stub_entry,
|
||||
ASSERT(constant_pool_allowed());
|
||||
const Code& target = Code::ZoneHandle(stub_entry.code());
|
||||
intptr_t call_start = buffer_.GetPosition();
|
||||
const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable);
|
||||
const intptr_t idx =
|
||||
object_pool_wrapper_.AddObject(target, ObjectPool::kPatchable);
|
||||
const int32_t offset = ObjectPool::element_offset(idx);
|
||||
LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
|
||||
movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset(entry_kind)));
|
||||
@@ -89,7 +90,8 @@ void Assembler::CallWithEquivalence(const StubEntry& stub_entry,
|
||||
void Assembler::Call(const StubEntry& stub_entry) {
|
||||
ASSERT(constant_pool_allowed());
|
||||
const Code& target = Code::ZoneHandle(stub_entry.code());
|
||||
const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable);
|
||||
const intptr_t idx =
|
||||
object_pool_wrapper_.FindObject(target, ObjectPool::kNotPatchable);
|
||||
const int32_t offset = ObjectPool::element_offset(idx);
|
||||
LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
|
||||
movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
|
||||
@@ -932,7 +934,8 @@ void Assembler::jmp(const ExternalLabel* label) {
|
||||
void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) {
|
||||
ASSERT((pp != PP) || constant_pool_allowed());
|
||||
const Code& target = Code::ZoneHandle(stub_entry.code());
|
||||
const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable);
|
||||
const intptr_t idx =
|
||||
object_pool_wrapper_.AddObject(target, ObjectPool::kPatchable);
|
||||
const int32_t offset = ObjectPool::element_offset(idx);
|
||||
movq(CODE_REG, Address::AddressBaseImm32(pp, offset - kHeapObjectTag));
|
||||
movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
|
||||
@@ -942,7 +945,8 @@ void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) {
|
||||
void Assembler::Jmp(const StubEntry& stub_entry, Register pp) {
|
||||
ASSERT((pp != PP) || constant_pool_allowed());
|
||||
const Code& target = Code::ZoneHandle(stub_entry.code());
|
||||
const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable);
|
||||
const intptr_t idx =
|
||||
object_pool_wrapper_.FindObject(target, ObjectPool::kNotPatchable);
|
||||
const int32_t offset = ObjectPool::element_offset(idx);
|
||||
movq(CODE_REG, FieldAddress(pp, offset));
|
||||
movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
|
||||
@@ -1142,7 +1146,8 @@ void Assembler::LoadFunctionFromCalleePool(Register dst,
|
||||
Register new_pp) {
|
||||
ASSERT(!constant_pool_allowed());
|
||||
ASSERT(new_pp != PP);
|
||||
const intptr_t idx = object_pool_wrapper_.FindObject(function, kNotPatchable);
|
||||
const intptr_t idx =
|
||||
object_pool_wrapper_.FindObject(function, ObjectPool::kNotPatchable);
|
||||
const int32_t offset = ObjectPool::element_offset(idx);
|
||||
movq(dst, Address::AddressBaseImm32(new_pp, offset - kHeapObjectTag));
|
||||
}
|
||||
@@ -1190,7 +1195,8 @@ void Assembler::CompareObject(Register reg, const Object& object) {
|
||||
if (Thread::CanLoadFromThread(object)) {
|
||||
cmpq(reg, Address(THR, Thread::OffsetFromThread(object)));
|
||||
} else if (CanLoadFromObjectPool(object)) {
|
||||
const intptr_t idx = object_pool_wrapper_.FindObject(object, kNotPatchable);
|
||||
const intptr_t idx =
|
||||
object_pool_wrapper_.FindObject(object, ObjectPool::kNotPatchable);
|
||||
const int32_t offset = ObjectPool::element_offset(idx);
|
||||
cmpq(reg, Address(PP, offset - kHeapObjectTag));
|
||||
} else {
|
||||
|
||||
@@ -686,7 +686,7 @@ class Assembler : public ValueObject {
|
||||
void LoadUniqueObject(Register dst, const Object& obj);
|
||||
void LoadNativeEntry(Register dst,
|
||||
const ExternalLabel* label,
|
||||
Patchability patchable);
|
||||
ObjectPool::Patchability patchable);
|
||||
void LoadFunctionFromCalleePool(Register dst,
|
||||
const Function& function,
|
||||
Register new_pp);
|
||||
|
||||
@@ -765,11 +765,11 @@ void FlowGraphCompiler::GenerateAssertAssignableViaTypeTestingStub(
|
||||
// on the call site to find out at which pool index the destination name is
|
||||
// located.
|
||||
const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
|
||||
Object::null_object(), Patchability::kPatchable);
|
||||
Object::null_object(), ObjectPool::Patchability::kPatchable);
|
||||
const intptr_t sub_type_cache_offset =
|
||||
ObjectPool::element_offset(sub_type_cache_index) - kHeapObjectTag;
|
||||
const intptr_t dst_name_index =
|
||||
__ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
|
||||
const intptr_t dst_name_index = __ object_pool_wrapper().AddObject(
|
||||
dst_name, ObjectPool::Patchability::kPatchable);
|
||||
ASSERT((sub_type_cache_index + 1) == dst_name_index);
|
||||
ASSERT(__ constant_pool_allowed());
|
||||
|
||||
@@ -839,7 +839,8 @@ void FlowGraphCompiler::EmitFrameEntry() {
|
||||
}
|
||||
__ CompareImmediate(R3, GetOptimizationThreshold());
|
||||
ASSERT(function_reg == R8);
|
||||
__ Branch(*StubCode::OptimizeFunction_entry(), kNotPatchable, new_pp, GE);
|
||||
__ Branch(*StubCode::OptimizeFunction_entry(), ObjectPool::kNotPatchable,
|
||||
new_pp, GE);
|
||||
}
|
||||
__ Comment("Enter frame");
|
||||
if (flow_graph().IsCompiledForOsr()) {
|
||||
|
||||
@@ -742,11 +742,11 @@ void FlowGraphCompiler::GenerateAssertAssignableViaTypeTestingStub(
|
||||
// on the call site to find out at which pool index the destination name is
|
||||
// located.
|
||||
const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
|
||||
Object::null_object(), Patchability::kPatchable);
|
||||
Object::null_object(), ObjectPool::Patchability::kPatchable);
|
||||
const intptr_t sub_type_cache_offset =
|
||||
ObjectPool::element_offset(sub_type_cache_index);
|
||||
const intptr_t dst_name_index =
|
||||
__ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
|
||||
const intptr_t dst_name_index = __ object_pool_wrapper().AddObject(
|
||||
dst_name, ObjectPool::Patchability::kPatchable);
|
||||
ASSERT((sub_type_cache_index + 1) == dst_name_index);
|
||||
ASSERT(__ constant_pool_allowed());
|
||||
|
||||
|
||||
@@ -756,11 +756,11 @@ void FlowGraphCompiler::GenerateAssertAssignableViaTypeTestingStub(
|
||||
// on the call site to find out at which pool index the destination name is
|
||||
// located.
|
||||
const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
|
||||
Object::null_object(), Patchability::kPatchable);
|
||||
Object::null_object(), ObjectPool::Patchability::kPatchable);
|
||||
const intptr_t sub_type_cache_offset =
|
||||
ObjectPool::element_offset(sub_type_cache_index) - kHeapObjectTag;
|
||||
const intptr_t dst_name_index =
|
||||
__ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
|
||||
const intptr_t dst_name_index = __ object_pool_wrapper().AddObject(
|
||||
dst_name, ObjectPool::Patchability::kPatchable);
|
||||
ASSERT((sub_type_cache_index + 1) == dst_name_index);
|
||||
ASSERT(__ constant_pool_allowed());
|
||||
|
||||
|
||||
@@ -992,7 +992,9 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
}
|
||||
__ LoadImmediate(R1, argc_tag);
|
||||
ExternalLabel label(entry);
|
||||
__ LoadNativeEntry(R9, &label, link_lazily() ? kPatchable : kNotPatchable);
|
||||
__ LoadNativeEntry(
|
||||
R9, &label,
|
||||
link_lazily() ? ObjectPool::kPatchable : ObjectPool::kNotPatchable);
|
||||
if (link_lazily()) {
|
||||
compiler->GeneratePatchableCall(token_pos(), *stub_entry,
|
||||
RawPcDescriptors::kOther, locs());
|
||||
|
||||
@@ -878,7 +878,9 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
}
|
||||
__ LoadImmediate(R1, argc_tag);
|
||||
ExternalLabel label(entry);
|
||||
__ LoadNativeEntry(R5, &label, link_lazily() ? kPatchable : kNotPatchable);
|
||||
__ LoadNativeEntry(
|
||||
R5, &label,
|
||||
link_lazily() ? ObjectPool::kPatchable : ObjectPool::kNotPatchable);
|
||||
if (link_lazily()) {
|
||||
compiler->GeneratePatchableCall(token_pos(), *stub_entry,
|
||||
RawPcDescriptors::kOther, locs());
|
||||
|
||||
@@ -981,11 +981,11 @@ EMIT_NATIVE_CODE(NativeCall,
|
||||
|
||||
const ExternalLabel trampoline_label(reinterpret_cast<uword>(trampoline));
|
||||
const intptr_t trampoline_kidx =
|
||||
__ object_pool_wrapper().FindNativeFunctionWrapper(&trampoline_label,
|
||||
kPatchable);
|
||||
__ object_pool_wrapper().FindNativeFunctionWrapper(
|
||||
&trampoline_label, ObjectPool::kPatchable);
|
||||
const ExternalLabel label(reinterpret_cast<uword>(function));
|
||||
const intptr_t target_kidx =
|
||||
__ object_pool_wrapper().FindNativeFunction(&label, kPatchable);
|
||||
const intptr_t target_kidx = __ object_pool_wrapper().FindNativeFunction(
|
||||
&label, ObjectPool::kPatchable);
|
||||
const intptr_t argc_tag_kidx =
|
||||
__ object_pool_wrapper().FindImmediate(static_cast<uword>(argc_tag));
|
||||
__ NativeCall(trampoline_kidx, target_kidx, argc_tag_kidx);
|
||||
|
||||
@@ -864,7 +864,7 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
if (link_lazily()) {
|
||||
stub_entry = StubCode::CallBootstrapNative_entry();
|
||||
ExternalLabel label(NativeEntry::LinkNativeCallEntry());
|
||||
__ LoadNativeEntry(RBX, &label, kPatchable);
|
||||
__ LoadNativeEntry(RBX, &label, ObjectPool::kPatchable);
|
||||
compiler->GeneratePatchableCall(token_pos(), *stub_entry,
|
||||
RawPcDescriptors::kOther, locs());
|
||||
} else {
|
||||
@@ -876,7 +876,7 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
stub_entry = StubCode::CallNoScopeNative_entry();
|
||||
}
|
||||
const ExternalLabel label(reinterpret_cast<uword>(native_c_function()));
|
||||
__ LoadNativeEntry(RBX, &label, kNotPatchable);
|
||||
__ LoadNativeEntry(RBX, &label, ObjectPool::kNotPatchable);
|
||||
compiler->GenerateCall(token_pos(), *stub_entry, RawPcDescriptors::kOther,
|
||||
locs());
|
||||
}
|
||||
|
||||
@@ -13487,7 +13487,7 @@ RawObjectPool* ObjectPool::New(intptr_t len) {
|
||||
result ^= raw;
|
||||
result.SetLength(len);
|
||||
for (intptr_t i = 0; i < len; i++) {
|
||||
result.SetTypeAt(i, ObjectPool::kImmediate);
|
||||
result.SetTypeAt(i, ObjectPool::kImmediate, ObjectPool::kPatchable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-4
@@ -4356,6 +4356,15 @@ class ObjectPool : public Object {
|
||||
kNativeFunctionWrapper,
|
||||
};
|
||||
|
||||
enum Patchability {
|
||||
kPatchable,
|
||||
kNotPatchable,
|
||||
};
|
||||
|
||||
class TypeBits : public BitField<uint8_t, EntryType, 0, 7> {};
|
||||
class PatchableBit
|
||||
: public BitField<uint8_t, Patchability, TypeBits::kNextBit, 1> {};
|
||||
|
||||
struct Entry {
|
||||
Entry() : raw_value_(), type_() {}
|
||||
explicit Entry(const Object* obj) : obj_(obj), type_(kTaggedObject) {}
|
||||
@@ -4382,11 +4391,17 @@ class ObjectPool : public Object {
|
||||
}
|
||||
|
||||
EntryType TypeAt(intptr_t index) const {
|
||||
return static_cast<EntryType>(raw_ptr()->entry_types()[index]);
|
||||
return TypeBits::decode(raw_ptr()->entry_bits()[index]);
|
||||
}
|
||||
void SetTypeAt(intptr_t index, EntryType type) const {
|
||||
StoreNonPointer(&raw_ptr()->entry_types()[index],
|
||||
static_cast<uint8_t>(type));
|
||||
|
||||
Patchability PatchableAt(intptr_t index) const {
|
||||
return PatchableBit::decode(raw_ptr()->entry_bits()[index]);
|
||||
}
|
||||
|
||||
void SetTypeAt(intptr_t index, EntryType type, Patchability patchable) const {
|
||||
const uint8_t bits =
|
||||
PatchableBit::encode(patchable) | TypeBits::encode(type);
|
||||
StoreNonPointer(&raw_ptr()->entry_bits()[index], bits);
|
||||
}
|
||||
|
||||
RawObject* ObjectAt(intptr_t index) const {
|
||||
|
||||
@@ -529,10 +529,10 @@ intptr_t RawObjectPool::VisitObjectPoolPointers(RawObjectPool* raw_obj,
|
||||
ObjectPointerVisitor* visitor) {
|
||||
const intptr_t length = raw_obj->ptr()->length_;
|
||||
RawObjectPool::Entry* entries = raw_obj->ptr()->data();
|
||||
uint8_t* entry_types = raw_obj->ptr()->entry_types();
|
||||
uint8_t* entry_bits = raw_obj->ptr()->entry_bits();
|
||||
for (intptr_t i = 0; i < length; ++i) {
|
||||
ObjectPool::EntryType entry_type =
|
||||
static_cast<ObjectPool::EntryType>(entry_types[i]);
|
||||
ObjectPool::TypeBits::decode(entry_bits[i]);
|
||||
if (entry_type == ObjectPool::kTaggedObject) {
|
||||
visitor->VisitPointer(&entries[i].raw_obj_);
|
||||
}
|
||||
|
||||
@@ -1368,12 +1368,10 @@ class RawObjectPool : public RawObject {
|
||||
Entry* data() { OPEN_ARRAY_START(Entry, Entry); }
|
||||
Entry const* data() const { OPEN_ARRAY_START(Entry, Entry); }
|
||||
|
||||
// The entry types are located after the last entry. They are interpreted
|
||||
// as ObjectPool::EntryType.
|
||||
uint8_t* entry_types() {
|
||||
return reinterpret_cast<uint8_t*>(&data()[length_]);
|
||||
}
|
||||
uint8_t const* entry_types() const {
|
||||
// The entry bits are located after the last entry. They are encoded versions
|
||||
// of `ObjectPool::TypeBits() | ObjectPool::PatchabililtyBit()`.
|
||||
uint8_t* entry_bits() { return reinterpret_cast<uint8_t*>(&data()[length_]); }
|
||||
uint8_t const* entry_bits() const {
|
||||
return reinterpret_cast<uint8_t const*>(&data()[length_]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user