1 // Copyright 2020 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_COMMON_EXTERNAL_POINTER_INL_H_
6 #define V8_COMMON_EXTERNAL_POINTER_INL_H_
7
8 #include "include/v8-internal.h"
9 #include "src/common/external-pointer.h"
10 #include "src/execution/isolate.h"
11
12 namespace v8 {
13 namespace internal {
14
DecodeExternalPointer(IsolateRoot isolate_root,ExternalPointer_t encoded_pointer,ExternalPointerTag tag)15 V8_INLINE Address DecodeExternalPointer(IsolateRoot isolate_root,
16 ExternalPointer_t encoded_pointer,
17 ExternalPointerTag tag) {
18 STATIC_ASSERT(kExternalPointerSize == kSystemPointerSize);
19 #ifdef V8_HEAP_SANDBOX
20 uint32_t index = static_cast<uint32_t>(encoded_pointer);
21 const Isolate* isolate = Isolate::FromRootAddress(isolate_root.address());
22 return isolate->external_pointer_table().get(index) ^ tag;
23 #else
24 return encoded_pointer;
25 #endif
26 }
27
InitExternalPointerField(Address field_address,Isolate * isolate)28 V8_INLINE void InitExternalPointerField(Address field_address,
29 Isolate* isolate) {
30 #ifdef V8_HEAP_SANDBOX
31 static_assert(kExternalPointerSize == kSystemPointerSize,
32 "Review the code below, once kExternalPointerSize is 4-byte "
33 "the address of the field will always be aligned");
34 ExternalPointer_t index = isolate->external_pointer_table().allocate();
35 base::WriteUnalignedValue<ExternalPointer_t>(field_address, index);
36 #else
37 // Nothing to do.
38 #endif // V8_HEAP_SANDBOX
39 }
40
InitExternalPointerField(Address field_address,Isolate * isolate,Address value,ExternalPointerTag tag)41 V8_INLINE void InitExternalPointerField(Address field_address, Isolate* isolate,
42 Address value, ExternalPointerTag tag) {
43 #ifdef V8_HEAP_SANDBOX
44 ExternalPointer_t index = isolate->external_pointer_table().allocate();
45 isolate->external_pointer_table().set(static_cast<uint32_t>(index),
46 value ^ tag);
47 static_assert(kExternalPointerSize == kSystemPointerSize,
48 "Review the code below, once kExternalPointerSize is 4-byte "
49 "the address of the field will always be aligned");
50 base::WriteUnalignedValue<ExternalPointer_t>(field_address, index);
51 #else
52 // Pointer compression causes types larger than kTaggedSize to be unaligned.
53 constexpr bool v8_pointer_compression_unaligned =
54 kExternalPointerSize > kTaggedSize;
55 ExternalPointer_t encoded_value = static_cast<ExternalPointer_t>(value);
56 if (v8_pointer_compression_unaligned) {
57 base::WriteUnalignedValue<ExternalPointer_t>(field_address, encoded_value);
58 } else {
59 base::Memory<ExternalPointer_t>(field_address) = encoded_value;
60 }
61 #endif // V8_HEAP_SANDBOX
62 }
63
ReadExternalPointerField(Address field_address,IsolateRoot isolate_root,ExternalPointerTag tag)64 V8_INLINE Address ReadExternalPointerField(Address field_address,
65 IsolateRoot isolate_root,
66 ExternalPointerTag tag) {
67 // Pointer compression causes types larger than kTaggedSize to be unaligned.
68 constexpr bool v8_pointer_compression_unaligned =
69 kExternalPointerSize > kTaggedSize;
70 ExternalPointer_t encoded_value;
71 if (v8_pointer_compression_unaligned) {
72 encoded_value = base::ReadUnalignedValue<ExternalPointer_t>(field_address);
73 } else {
74 encoded_value = base::Memory<ExternalPointer_t>(field_address);
75 }
76 return DecodeExternalPointer(isolate_root, encoded_value, tag);
77 }
78
WriteExternalPointerField(Address field_address,Isolate * isolate,Address value,ExternalPointerTag tag)79 V8_INLINE void WriteExternalPointerField(Address field_address,
80 Isolate* isolate, Address value,
81 ExternalPointerTag tag) {
82 #ifdef V8_HEAP_SANDBOX
83 static_assert(kExternalPointerSize == kSystemPointerSize,
84 "Review the code below, once kExternalPointerSize is 4-byte "
85 "the address of the field will always be aligned");
86
87 ExternalPointer_t index =
88 base::ReadUnalignedValue<ExternalPointer_t>(field_address);
89 isolate->external_pointer_table().set(static_cast<uint32_t>(index),
90 value ^ tag);
91 #else
92 // Pointer compression causes types larger than kTaggedSize to be unaligned.
93 constexpr bool v8_pointer_compression_unaligned =
94 kExternalPointerSize > kTaggedSize;
95 ExternalPointer_t encoded_value = static_cast<ExternalPointer_t>(value);
96 if (v8_pointer_compression_unaligned) {
97 base::WriteUnalignedValue<ExternalPointer_t>(field_address, encoded_value);
98 } else {
99 base::Memory<ExternalPointer_t>(field_address) = encoded_value;
100 }
101 #endif // V8_HEAP_SANDBOX
102 }
103
104 } // namespace internal
105 } // namespace v8
106
107 #endif // V8_COMMON_EXTERNAL_POINTER_INL_H_
108