• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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