Commit 5c93a008 authored by Shu-yu Guo's avatar Shu-yu Guo Committed by Commit Bot

[ptr-cage] Use Isolate directly for decoding external pointers

This removes the heap sandbox's dependency on being able to reconstruct
an Isolate from the pointer cage base address.

Bug: v8:11460
Change-Id: I501ace5b83a2cefdf717de0d7387fd816edfb3f1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2783673
Auto-Submit: Shu-yu Guo <syg@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73887}
parent 0e2d3413
......@@ -12,19 +12,12 @@
namespace v8 {
namespace internal {
V8_INLINE Address DecodeExternalPointer(PtrComprCageBase isolate_root,
V8_INLINE Address DecodeExternalPointer(const Isolate* isolate,
ExternalPointer_t encoded_pointer,
ExternalPointerTag tag) {
STATIC_ASSERT(kExternalPointerSize == kSystemPointerSize);
#ifdef V8_HEAP_SANDBOX
// TODO(syg): V8_HEAP_SANDBOX doesn't work with pointer cage
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
#error "V8_HEAP_SANDBOX requires per-Isolate pointer compression cage"
#endif
uint32_t index = static_cast<uint32_t>(encoded_pointer);
const Isolate* isolate = Isolate::FromRootAddress(isolate_root.address());
return isolate->external_pointer_table().get(index) ^ tag;
#else
return encoded_pointer;
......@@ -68,7 +61,7 @@ V8_INLINE void InitExternalPointerField(Address field_address, Isolate* isolate,
}
V8_INLINE Address ReadExternalPointerField(Address field_address,
PtrComprCageBase cage_base,
const Isolate* isolate,
ExternalPointerTag tag) {
// Pointer compression causes types larger than kTaggedSize to be unaligned.
constexpr bool v8_pointer_compression_unaligned =
......@@ -79,7 +72,7 @@ V8_INLINE Address ReadExternalPointerField(Address field_address,
} else {
encoded_value = base::Memory<ExternalPointer_t>(field_address);
}
return DecodeExternalPointer(cage_base, encoded_value, tag);
return DecodeExternalPointer(isolate, encoded_value, tag);
}
V8_INLINE void WriteExternalPointerField(Address field_address,
......
......@@ -12,7 +12,7 @@ namespace internal {
// Convert external pointer from on-V8-heap representation to an actual external
// pointer value.
V8_INLINE Address DecodeExternalPointer(PtrComprCageBase isolate,
V8_INLINE Address DecodeExternalPointer(const Isolate* isolate,
ExternalPointer_t encoded_pointer,
ExternalPointerTag tag);
......@@ -34,7 +34,7 @@ V8_INLINE void InitExternalPointerField(Address field_address, Isolate* isolate,
// Reads external pointer for the field, and decodes it if the sandbox is
// enabled.
V8_INLINE Address ReadExternalPointerField(Address field_address,
PtrComprCageBase isolate,
const Isolate* isolate,
ExternalPointerTag tag);
// Encodes value if the sandbox is enabled and writes it into the field.
......
......@@ -468,13 +468,13 @@ void PrintSloppyArgumentElements(std::ostream& os, ElementsKind kind,
}
}
void PrintEmbedderData(PtrComprCageBase cage_base, std::ostream& os,
void PrintEmbedderData(Isolate* isolate, std::ostream& os,
EmbedderDataSlot slot) {
DisallowGarbageCollection no_gc;
Object value = slot.load_tagged();
os << Brief(value);
void* raw_pointer;
if (slot.ToAlignedPointer(cage_base, &raw_pointer)) {
if (slot.ToAlignedPointer(isolate, &raw_pointer)) {
os << ", aligned pointer: " << raw_pointer;
}
}
......@@ -579,11 +579,11 @@ static void JSObjectPrintBody(std::ostream& os,
}
int embedder_fields = obj.GetEmbedderFieldCount();
if (embedder_fields > 0) {
PtrComprCageBase cage_base = GetPtrComprCageBase(obj);
Isolate* isolate = GetIsolateForHeapSandbox(obj);
os << " - embedder fields = {";
for (int i = 0; i < embedder_fields; i++) {
os << "\n ";
PrintEmbedderData(cage_base, os, EmbedderDataSlot(obj, i));
PrintEmbedderData(isolate, os, EmbedderDataSlot(obj, i));
}
os << "\n }\n";
}
......@@ -762,14 +762,14 @@ void ObjectBoilerplateDescription::ObjectBoilerplateDescriptionPrint(
}
void EmbedderDataArray::EmbedderDataArrayPrint(std::ostream& os) {
PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
Isolate* isolate = GetIsolateForHeapSandbox(*this);
PrintHeader(os, "EmbedderDataArray");
os << "\n - length: " << length();
EmbedderDataSlot start(*this, 0);
EmbedderDataSlot end(*this, length());
for (EmbedderDataSlot slot = start; slot < end; ++slot) {
os << "\n ";
PrintEmbedderData(cage_base, os, slot);
PrintEmbedderData(isolate, os, slot);
}
os << "\n";
}
......
......@@ -86,6 +86,17 @@ V8_INLINE bool GetIsolateFromHeapObject(HeapObject object, Isolate** isolate) {
#endif // V8_COMPRESS_POINTERS, V8_ENABLE_THIRD_PARTY_HEAP
}
// Use this function instead of Internals::GetIsolateForHeapSandbox for internal
// code, as this function is fully inlinable.
V8_INLINE static Isolate* GetIsolateForHeapSandbox(HeapObject object) {
#ifdef V8_HEAP_SANDBOX
return GetIsolateFromWritableObject(object);
#else
// Not used in non-sandbox mode.
return nullptr;
#endif
}
} // namespace internal
} // namespace v8
......
......@@ -382,11 +382,11 @@ namespace {
void ExtractInternalFields(JSObject jsobject, void** embedder_fields, int len) {
int field_count = jsobject.GetEmbedderFieldCount();
PtrComprCageBase cage_base = GetPtrComprCageBase(jsobject);
Isolate* isolate = GetIsolateForHeapSandbox(jsobject);
for (int i = 0; i < len; ++i) {
if (field_count == i) break;
void* pointer;
if (EmbedderDataSlot(jsobject, i).ToAlignedPointer(cage_base, &pointer)) {
if (EmbedderDataSlot(jsobject, i).ToAlignedPointer(isolate, &pointer)) {
embedder_fields[i] = pointer;
}
}
......
......@@ -242,8 +242,9 @@ Map Context::GetInitialJSArrayMap(ElementsKind kind) const {
}
DEF_GETTER(NativeContext, microtask_queue, MicrotaskQueue*) {
Isolate* isolate = GetIsolateForHeapSandbox(*this);
return reinterpret_cast<MicrotaskQueue*>(ReadExternalPointerField(
kMicrotaskQueueOffset, cage_base, kNativeContextMicrotaskQueueTag));
kMicrotaskQueueOffset, isolate, kNativeContextMicrotaskQueueTag));
}
void NativeContext::AllocateExternalPointerEntries(Isolate* isolate) {
......
......@@ -81,7 +81,7 @@ void EmbedderDataSlot::store_tagged(JSObject object, int embedder_field_index,
#endif
}
bool EmbedderDataSlot::ToAlignedPointer(PtrComprCageBase isolate_root,
bool EmbedderDataSlot::ToAlignedPointer(Isolate* isolate,
void** out_pointer) const {
// We don't care about atomicity of access here because embedder slots
// are accessed this way only from the main thread via API during "mutator"
......@@ -89,14 +89,7 @@ bool EmbedderDataSlot::ToAlignedPointer(PtrComprCageBase isolate_root,
// at the tagged part of the embedder slot but read-only access is ok).
Address raw_value;
#ifdef V8_HEAP_SANDBOX
// TODO(syg): V8_HEAP_SANDBOX doesn't work with pointer cage
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
#error "V8_HEAP_SANDBOX requires per-Isolate pointer compression cage"
#endif
uint32_t index = base::Memory<uint32_t>(address() + kRawPayloadOffset);
const Isolate* isolate = Isolate::FromRootAddress(isolate_root.address());
raw_value = isolate->external_pointer_table().get(index) ^
kEmbedderDataSlotPayloadTag;
#else
......@@ -114,18 +107,11 @@ bool EmbedderDataSlot::ToAlignedPointer(PtrComprCageBase isolate_root,
return HAS_SMI_TAG(raw_value);
}
bool EmbedderDataSlot::ToAlignedPointerSafe(PtrComprCageBase isolate_root,
bool EmbedderDataSlot::ToAlignedPointerSafe(Isolate* isolate,
void** out_pointer) const {
#ifdef V8_HEAP_SANDBOX
// TODO(syg): V8_HEAP_SANDBOX doesn't work with pointer cage
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
#error "V8_HEAP_SANDBOX requires per-Isolate pointer compression cage"
#endif
uint32_t index = base::Memory<uint32_t>(address() + kRawPayloadOffset);
Address raw_value;
const Isolate* isolate = Isolate::FromRootAddress(isolate_root.address());
if (isolate->external_pointer_table().is_valid_index(index)) {
raw_value = isolate->external_pointer_table().get(index) ^
kEmbedderDataSlotPayloadTag;
......@@ -134,7 +120,7 @@ bool EmbedderDataSlot::ToAlignedPointerSafe(PtrComprCageBase isolate_root,
}
return false;
#else
return ToAlignedPointer(isolate_root, out_pointer);
return ToAlignedPointer(isolate, out_pointer);
#endif // V8_HEAP_SANDBOX
}
......
......@@ -75,8 +75,7 @@ class EmbedderDataSlot
// When V8 heap sandbox is enabled, calling this method when the raw part of
// the slot does not contain valid external pointer table index is undefined
// behaviour and most likely result in crashes.
V8_INLINE bool ToAlignedPointer(PtrComprCageBase isolate_root,
void** out_result) const;
V8_INLINE bool ToAlignedPointer(Isolate* isolate, void** out_result) const;
// Same as ToAlignedPointer() but with a workaround for V8 heap sandbox.
// When V8 heap sandbox is enabled, this method doesn't crash when the raw
......@@ -87,7 +86,7 @@ class EmbedderDataSlot
//
// Call this function if you are not sure whether the slot contains valid
// external pointer or not.
V8_INLINE bool ToAlignedPointerSafe(PtrComprCageBase isolate_root,
V8_INLINE bool ToAlignedPointerSafe(Isolate* isolate,
void** out_result) const;
// Returns true if the pointer was successfully stored or false it the pointer
......
......@@ -29,7 +29,8 @@ bool Foreign::IsNormalized(Object value) {
}
DEF_GETTER(Foreign, foreign_address, Address) {
return ReadExternalPointerField(kForeignAddressOffset, cage_base,
Isolate* isolate = GetIsolateForHeapSandbox(*this);
return ReadExternalPointerField(kForeignAddressOffset, isolate,
kForeignForeignAddressTag);
}
......
......@@ -43,7 +43,8 @@ void JSArrayBuffer::set_byte_length(size_t value) {
}
DEF_GETTER(JSArrayBuffer, backing_store, void*) {
Address value = ReadExternalPointerField(kBackingStoreOffset, cage_base,
Isolate* isolate = GetIsolateForHeapSandbox(*this);
Address value = ReadExternalPointerField(kBackingStoreOffset, isolate,
kArrayBufferBackingStoreTag);
return reinterpret_cast<void*>(value);
}
......@@ -199,7 +200,8 @@ void JSTypedArray::set_length(size_t value) {
}
DEF_GETTER(JSTypedArray, external_pointer, Address) {
return ReadExternalPointerField(kExternalPointerOffset, cage_base,
Isolate* isolate = GetIsolateForHeapSandbox(*this);
return ReadExternalPointerField(kExternalPointerOffset, isolate,
kTypedArrayExternalPointerTag);
}
......@@ -320,8 +322,9 @@ MaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate,
}
DEF_GETTER(JSDataView, data_pointer, void*) {
Isolate* isolate = GetIsolateForHeapSandbox(*this);
return reinterpret_cast<void*>(ReadExternalPointerField(
kDataPointerOffset, cage_base, kDataViewDataPointerTag));
kDataPointerOffset, isolate, kDataViewDataPointerTag));
}
void JSDataView::AllocateExternalPointerEntries(Isolate* isolate) {
......
......@@ -631,10 +631,9 @@ void Object::InitExternalPointerField(size_t offset, Isolate* isolate,
i::InitExternalPointerField(field_address(offset), isolate, value, tag);
}
Address Object::ReadExternalPointerField(size_t offset,
PtrComprCageBase isolate_root,
Address Object::ReadExternalPointerField(size_t offset, Isolate* isolate,
ExternalPointerTag tag) const {
return i::ReadExternalPointerField(field_address(offset), isolate_root, tag);
return i::ReadExternalPointerField(field_address(offset), isolate, tag);
}
void Object::WriteExternalPointerField(size_t offset, Isolate* isolate,
......
......@@ -673,8 +673,7 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
inline void InitExternalPointerField(size_t offset, Isolate* isolate);
inline void InitExternalPointerField(size_t offset, Isolate* isolate,
Address value, ExternalPointerTag tag);
inline Address ReadExternalPointerField(size_t offset,
PtrComprCageBase isolate_root,
inline Address ReadExternalPointerField(size_t offset, Isolate* isolate,
ExternalPointerTag tag) const;
inline void WriteExternalPointerField(size_t offset, Isolate* isolate,
Address value, ExternalPointerTag tag);
......
......@@ -862,7 +862,8 @@ void ExternalString::AllocateExternalPointerEntries(Isolate* isolate) {
}
DEF_GETTER(ExternalString, resource_as_address, Address) {
return ReadExternalPointerField(kResourceOffset, cage_base,
Isolate* isolate = GetIsolateForHeapSandbox(*this);
return ReadExternalPointerField(kResourceOffset, isolate,
kExternalStringResourceTag);
}
......
......@@ -460,12 +460,6 @@ int WasmArray::GcSafeSizeFor(Map map, int length) {
void WasmTypeInfo::clear_foreign_address(Isolate* isolate) {
#ifdef V8_HEAP_SANDBOX
// TODO(syg): V8_HEAP_SANDBOX doesn't work with pointer cage
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
#error "V8_HEAP_SANDBOX requires per-Isolate pointer compression cage"
#endif
// Due to the type-specific pointer tags for external pointers, we need to
// allocate an entry in the table here even though it will just store nullptr.
AllocateExternalPointerEntries(isolate);
......
......@@ -347,10 +347,10 @@ class ReadStringVisitor : public TqObjectVisitor {
ExternalPointer_t resource_data =
GetOrFinish(object->GetResourceDataValue(accessor_));
#ifdef V8_COMPRESS_POINTERS
uintptr_t data_address = static_cast<uintptr_t>(
DecodeExternalPointer(GetPtrComprCageBaseFromOnHeapAddress(
heap_addresses_.any_heap_pointer),
resource_data, kExternalStringResourceDataTag));
Isolate* isolate = GetIsolateForHeapSandbox(
HeapObject::unchecked_cast(Object(heap_addresses_.any_heap_pointer)));
uintptr_t data_address = static_cast<uintptr_t>(DecodeExternalPointer(
isolate, resource_data, kExternalStringResourceDataTag));
#else
uintptr_t data_address = static_cast<uintptr_t>(resource_data);
#endif // V8_COMPRESS_POINTERS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment