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