[arm64] Fix handling of handles in assembler
Previously, the handle's location was used as a proxy for the heap object, i.e, we put the handle into the constant pool, to avoid the need for GC visiting the constant pool entries during code generation. The handle locations are replaced by the corresponding heap object when the code is copied to the heap. This CL changes the handling in the assembler: Instead of putting in the handle location (which is a machine word) we put in a small index number into a table. This will be useful for putting 32bit constants into the constant pool. This new approach also has the advantage that ordering the constant pool entries by value produces a deterministic order after this change. Change-Id: Id47d56d487a0b64d1d1504a47937c8779ee02b13 Bug: v8:7703 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1648094 Commit-Queue: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#62144}
This commit is contained in:
parent
e79e81cdf5
commit
66412e0f55
@ -503,10 +503,24 @@ Handle<Code> Assembler::code_target_object_handle_at(Address pc) {
|
||||
}
|
||||
}
|
||||
|
||||
Handle<HeapObject> Assembler::compressed_embedded_object_handle_at(Address pc) {
|
||||
AssemblerBase::EmbeddedObjectIndex
|
||||
Assembler::embedded_object_index_referenced_from(Address pc) {
|
||||
Instruction* instr = reinterpret_cast<Instruction*>(pc);
|
||||
CHECK(!instr->IsLdrLiteralX());
|
||||
return GetCompressedEmbeddedObject(ReadUnalignedValue<int32_t>(pc));
|
||||
CHECK(instr->IsLdrLiteralX());
|
||||
STATIC_ASSERT(sizeof(EmbeddedObjectIndex) == sizeof(intptr_t));
|
||||
return Memory<EmbeddedObjectIndex>(target_pointer_address_at(pc));
|
||||
}
|
||||
|
||||
void Assembler::set_embedded_object_index_referenced_from(
|
||||
Address pc, EmbeddedObjectIndex data) {
|
||||
Instruction* instr = reinterpret_cast<Instruction*>(pc);
|
||||
CHECK(instr->IsLdrLiteralX());
|
||||
Memory<EmbeddedObjectIndex>(target_pointer_address_at(pc)) = data;
|
||||
}
|
||||
|
||||
Handle<HeapObject> Assembler::target_object_handle_at(Address pc) {
|
||||
return GetEmbeddedObject(
|
||||
Assembler::embedded_object_index_referenced_from(pc));
|
||||
}
|
||||
|
||||
Address Assembler::runtime_entry_at(Address pc) {
|
||||
@ -637,8 +651,7 @@ HeapObject RelocInfo::target_object_no_host(Isolate* isolate) {
|
||||
|
||||
Handle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
|
||||
if (IsFullEmbeddedObject(rmode_)) {
|
||||
return Handle<HeapObject>(reinterpret_cast<Address*>(
|
||||
Assembler::target_address_at(pc_, constant_pool_)));
|
||||
return origin->target_object_handle_at(pc_);
|
||||
} else {
|
||||
DCHECK(IsCodeTarget(rmode_));
|
||||
return origin->code_target_object_handle_at(pc_);
|
||||
|
@ -548,14 +548,16 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
|
||||
case HeapObjectRequest::kHeapNumber: {
|
||||
Handle<HeapObject> object = isolate->factory()->NewHeapNumber(
|
||||
request.heap_number(), AllocationType::kOld);
|
||||
set_target_address_at(pc, 0 /* unused */, object.address());
|
||||
EmbeddedObjectIndex index = AddEmbeddedObject(object);
|
||||
set_embedded_object_index_referenced_from(pc, index);
|
||||
break;
|
||||
}
|
||||
case HeapObjectRequest::kStringConstant: {
|
||||
const StringConstantBase* str = request.string();
|
||||
CHECK_NOT_NULL(str);
|
||||
set_target_address_at(pc, 0 /* unused */,
|
||||
str->AllocateStringConstant(isolate).address());
|
||||
EmbeddedObjectIndex index =
|
||||
AddEmbeddedObject(str->AllocateStringConstant(isolate));
|
||||
set_embedded_object_index_referenced_from(pc, index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -4484,6 +4486,10 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data,
|
||||
RelocInfo::IsConstPool(rmode) || RelocInfo::IsVeneerPool(rmode));
|
||||
// These modes do not need an entry in the constant pool.
|
||||
} else if (constant_pool_mode == NEEDS_POOL_ENTRY) {
|
||||
if (RelocInfo::IsEmbeddedObjectMode(rmode)) {
|
||||
Handle<HeapObject> handle(reinterpret_cast<Address*>(data));
|
||||
data = AddEmbeddedObject(handle);
|
||||
}
|
||||
if (!constpool_.RecordEntry(data, rmode)) return;
|
||||
}
|
||||
// For modes that cannot use the constant pool, a different sequence of
|
||||
|
@ -314,8 +314,11 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
||||
// Returns the handle for the code object called at 'pc'.
|
||||
// This might need to be temporarily encoded as an offset into code_targets_.
|
||||
inline Handle<Code> code_target_object_handle_at(Address pc);
|
||||
|
||||
inline Handle<HeapObject> compressed_embedded_object_handle_at(Address pc);
|
||||
inline EmbeddedObjectIndex embedded_object_index_referenced_from(Address pc);
|
||||
inline void set_embedded_object_index_referenced_from(
|
||||
Address p, EmbeddedObjectIndex index);
|
||||
// Returns the handle for the heap object referenced at 'pc'.
|
||||
inline Handle<HeapObject> target_object_handle_at(Address pc);
|
||||
|
||||
// Returns the target address for a runtime function for the call encoded
|
||||
// at 'pc'.
|
||||
|
@ -226,16 +226,17 @@ int AssemblerBase::AddCodeTarget(Handle<Code> target) {
|
||||
}
|
||||
}
|
||||
|
||||
int AssemblerBase::AddCompressedEmbeddedObject(Handle<HeapObject> object) {
|
||||
int current = static_cast<int>(compressed_embedded_objects_.size());
|
||||
compressed_embedded_objects_.push_back(object);
|
||||
AssemblerBase::EmbeddedObjectIndex AssemblerBase::AddEmbeddedObject(
|
||||
Handle<HeapObject> object) {
|
||||
EmbeddedObjectIndex current = embedded_objects_.size();
|
||||
embedded_objects_.push_back(object);
|
||||
return current;
|
||||
}
|
||||
|
||||
Handle<HeapObject> AssemblerBase::GetCompressedEmbeddedObject(
|
||||
intptr_t index) const {
|
||||
DCHECK_LT(static_cast<size_t>(index), compressed_embedded_objects_.size());
|
||||
return compressed_embedded_objects_[index];
|
||||
Handle<HeapObject> AssemblerBase::GetEmbeddedObject(
|
||||
EmbeddedObjectIndex index) const {
|
||||
DCHECK_LT(index, embedded_objects_.size());
|
||||
return embedded_objects_[index];
|
||||
}
|
||||
|
||||
Handle<Code> AssemblerBase::GetCodeTarget(intptr_t code_target_index) const {
|
||||
|
@ -272,8 +272,11 @@ class V8_EXPORT_PRIVATE AssemblerBase : public Malloced {
|
||||
int AddCodeTarget(Handle<Code> target);
|
||||
Handle<Code> GetCodeTarget(intptr_t code_target_index) const;
|
||||
|
||||
int AddCompressedEmbeddedObject(Handle<HeapObject> object);
|
||||
Handle<HeapObject> GetCompressedEmbeddedObject(intptr_t index) const;
|
||||
// Add 'object' to the {embedded_objects_} vector and return the index at
|
||||
// which it is stored.
|
||||
using EmbeddedObjectIndex = size_t;
|
||||
EmbeddedObjectIndex AddEmbeddedObject(Handle<HeapObject> object);
|
||||
Handle<HeapObject> GetEmbeddedObject(EmbeddedObjectIndex index) const;
|
||||
|
||||
// The buffer into which code and relocation info are generated.
|
||||
std::unique_ptr<AssemblerBuffer> buffer_;
|
||||
@ -321,12 +324,11 @@ class V8_EXPORT_PRIVATE AssemblerBase : public Malloced {
|
||||
// the code handle in the vector instead.
|
||||
std::vector<Handle<Code>> code_targets_;
|
||||
|
||||
// When pointer compression is enabled, we need to store indexes to this
|
||||
// table in the code until we are ready to copy the code and embed the real
|
||||
// object pointers. We don't need to do the same thing for non-compressed
|
||||
// embedded objects, because we've got enough space (kPointerSize) in the
|
||||
// code stream to just embed the address of the object handle.
|
||||
std::vector<Handle<HeapObject>> compressed_embedded_objects_;
|
||||
// If an assembler needs a small number to refer to a heap object handle
|
||||
// (for example, because there are only 32bit available on a 64bit arch), the
|
||||
// assembler adds the object into this vector using AddEmbeddedObject, and
|
||||
// may then refer to the heap object using the handle's index in this vector.
|
||||
std::vector<Handle<HeapObject>> embedded_objects_;
|
||||
|
||||
const AssemblerOptions options_;
|
||||
uint64_t enabled_cpu_features_;
|
||||
|
@ -246,7 +246,7 @@ Handle<Code> Assembler::code_target_object_handle_at(Address pc) {
|
||||
}
|
||||
|
||||
Handle<HeapObject> Assembler::compressed_embedded_object_handle_at(Address pc) {
|
||||
return GetCompressedEmbeddedObject(ReadUnalignedValue<int32_t>(pc));
|
||||
return GetEmbeddedObject(ReadUnalignedValue<uint32_t>(pc));
|
||||
}
|
||||
|
||||
Address Assembler::runtime_entry_at(Address pc) {
|
||||
|
@ -1468,8 +1468,9 @@ void TurboAssembler::Move(Register result, Handle<HeapObject> object,
|
||||
}
|
||||
}
|
||||
if (RelocInfo::IsCompressedEmbeddedObject(rmode)) {
|
||||
int compressed_embedded_object_index = AddCompressedEmbeddedObject(object);
|
||||
movl(result, Immediate(compressed_embedded_object_index, rmode));
|
||||
EmbeddedObjectIndex index = AddEmbeddedObject(object);
|
||||
DCHECK(is_uint32(index));
|
||||
movl(result, Immediate(static_cast<int>(index), rmode));
|
||||
} else {
|
||||
DCHECK(RelocInfo::IsFullEmbeddedObject(rmode));
|
||||
movq(result, Immediate64(object.address(), rmode));
|
||||
|
Loading…
Reference in New Issue
Block a user