[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:
Martin Kustermann
2018-08-23 07:06:26 +00:00
committed by commit-bot@chromium.org
parent 4c2169e63f
commit 5d7ca9cd1e
20 changed files with 166 additions and 125 deletions
+8 -12
View File
@@ -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;
+27 -28
View File
@@ -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 {
+47 -27
View File
@@ -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);
+13 -7
View File
@@ -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());
+3 -1
View File
@@ -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());
+3 -1
View File
@@ -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());
+4 -4
View File
@@ -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);
+2 -2
View File
@@ -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());
}
+1 -1
View File
@@ -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
View File
@@ -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 {
+2 -2
View File
@@ -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_);
}
+4 -6
View File
@@ -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_]);
}