1 // Copyright 2019 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_EXECUTION_ISOLATE_UTILS_INL_H_
6 #define V8_EXECUTION_ISOLATE_UTILS_INL_H_
7
8 #include "src/common/ptr-compr-inl.h"
9 #include "src/execution/isolate-utils.h"
10 #include "src/execution/isolate.h"
11 #include "src/heap/heap-write-barrier-inl.h"
12
13 namespace v8 {
14 namespace internal {
15
16 #ifdef V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
17
18 // Aliases for GetPtrComprCageBase when
19 // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE. Each Isolate has its own cage, whose
20 // base address is also the Isolate root.
GetIsolateRootAddress(Address on_heap_addr)21 V8_INLINE constexpr Address GetIsolateRootAddress(Address on_heap_addr) {
22 return GetPtrComprCageBaseAddress(on_heap_addr);
23 }
24
GetIsolateRootAddress(PtrComprCageBase cage_base)25 V8_INLINE Address GetIsolateRootAddress(PtrComprCageBase cage_base) {
26 return cage_base.address();
27 }
28
29 #else
30
31 V8_INLINE Address GetIsolateRootAddress(Address on_heap_addr) { UNREACHABLE(); }
32
33 V8_INLINE Address GetIsolateRootAddress(PtrComprCageBase cage_base) {
34 UNREACHABLE();
35 }
36
37 #endif // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
38
GetHeapFromWritableObject(HeapObject object)39 V8_INLINE Heap* GetHeapFromWritableObject(HeapObject object) {
40 // Avoid using the below GetIsolateFromWritableObject because we want to be
41 // able to get the heap, but not the isolate, for off-thread objects.
42
43 #if defined V8_ENABLE_THIRD_PARTY_HEAP
44 return Heap::GetIsolateFromWritableObject(object)->heap();
45 #elif defined(V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE) && \
46 !defined(V8_EXTERNAL_CODE_SPACE)
47 Isolate* isolate =
48 Isolate::FromRootAddress(GetIsolateRootAddress(object.ptr()));
49 DCHECK_NOT_NULL(isolate);
50 return isolate->heap();
51 #else
52 heap_internals::MemoryChunk* chunk =
53 heap_internals::MemoryChunk::FromHeapObject(object);
54 return chunk->GetHeap();
55 #endif // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE, V8_ENABLE_THIRD_PARTY_HEAP
56 }
57
GetIsolateFromWritableObject(HeapObject object)58 V8_INLINE Isolate* GetIsolateFromWritableObject(HeapObject object) {
59 #ifdef V8_ENABLE_THIRD_PARTY_HEAP
60 return Heap::GetIsolateFromWritableObject(object);
61 #elif defined(V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE) && \
62 !defined(V8_EXTERNAL_CODE_SPACE)
63 Isolate* isolate =
64 Isolate::FromRootAddress(GetIsolateRootAddress(object.ptr()));
65 DCHECK_NOT_NULL(isolate);
66 return isolate;
67 #else
68 return Isolate::FromHeap(GetHeapFromWritableObject(object));
69 #endif // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE, V8_ENABLE_THIRD_PARTY_HEAP
70 }
71
GetIsolateFromHeapObject(HeapObject object,Isolate ** isolate)72 V8_INLINE bool GetIsolateFromHeapObject(HeapObject object, Isolate** isolate) {
73 #ifdef V8_ENABLE_THIRD_PARTY_HEAP
74 *isolate = Heap::GetIsolateFromWritableObject(object);
75 return true;
76 #elif defined V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
77 *isolate = GetIsolateFromWritableObject(object);
78 return true;
79 #else
80 heap_internals::MemoryChunk* chunk =
81 heap_internals::MemoryChunk::FromHeapObject(object);
82 if (chunk->InReadOnlySpace()) {
83 *isolate = nullptr;
84 return false;
85 }
86 *isolate = Isolate::FromHeap(chunk->GetHeap());
87 return true;
88 #endif // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE, V8_ENABLE_THIRD_PARTY_HEAP
89 }
90
91 // Use this function instead of Internals::GetIsolateForSandbox for internal
92 // code, as this function is fully inlinable.
GetIsolateForSandbox(HeapObject object)93 V8_INLINE static Isolate* GetIsolateForSandbox(HeapObject object) {
94 #ifdef V8_SANDBOXED_EXTERNAL_POINTERS
95 return GetIsolateFromWritableObject(object);
96 #else
97 // Not used in non-sandbox mode.
98 return nullptr;
99 #endif
100 }
101
102 // This is an external code space friendly version of GetPtrComprCageBase(..)
103 // which also works for objects located in external code space.
104 //
105 // NOTE: it's supposed to be used only for the cases where performance doesn't
106 // matter. For example, in debug only code or in debugging macros.
107 // In production code the preferred way is to use precomputed cage base value
108 // which is a result of PtrComprCageBase{isolate} or GetPtrComprCageBase()
109 // applied to a heap object which is known to not be a part of external code
110 // space.
GetPtrComprCageBaseSlow(HeapObject object)111 V8_INLINE PtrComprCageBase GetPtrComprCageBaseSlow(HeapObject object) {
112 if (V8_EXTERNAL_CODE_SPACE_BOOL) {
113 Isolate* isolate;
114 if (GetIsolateFromHeapObject(object, &isolate)) {
115 return PtrComprCageBase{isolate};
116 }
117 // If the Isolate can't be obtained then the heap object is a read-only
118 // one and therefore not a Code object, so fallback to auto-computing cage
119 // base value.
120 }
121 return GetPtrComprCageBase(object);
122 }
123
124 } // namespace internal
125 } // namespace v8
126
127 #endif // V8_EXECUTION_ISOLATE_UTILS_INL_H_
128