1 | // Copyright 2018 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_EXTERNAL_REFERENCE_H_ |
6 | #define V8_EXTERNAL_REFERENCE_H_ |
7 | |
8 | #include "src/globals.h" |
9 | #include "src/runtime/runtime.h" |
10 | |
11 | namespace v8 { |
12 | |
13 | class ApiFunction; |
14 | |
15 | namespace internal { |
16 | |
17 | class Isolate; |
18 | class Page; |
19 | class SCTableReference; |
20 | class StatsCounter; |
21 | |
22 | //------------------------------------------------------------------------------ |
23 | // External references |
24 | |
25 | #define EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(V) \ |
26 | V(isolate_address, "isolate") \ |
27 | V(builtins_address, "builtins") \ |
28 | V(handle_scope_implementer_address, \ |
29 | "Isolate::handle_scope_implementer_address") \ |
30 | V(address_of_interpreter_entry_trampoline_instruction_start, \ |
31 | "Address of the InterpreterEntryTrampoline instruction start") \ |
32 | V(interpreter_dispatch_counters, "Interpreter::dispatch_counters") \ |
33 | V(interpreter_dispatch_table_address, "Interpreter::dispatch_table_address") \ |
34 | V(date_cache_stamp, "date_cache_stamp") \ |
35 | V(stress_deopt_count, "Isolate::stress_deopt_count_address()") \ |
36 | V(force_slow_path, "Isolate::force_slow_path_address()") \ |
37 | V(isolate_root, "Isolate::isolate_root()") \ |
38 | V(allocation_sites_list_address, "Heap::allocation_sites_list_address()") \ |
39 | V(address_of_stack_limit, "StackGuard::address_of_jslimit()") \ |
40 | V(address_of_real_stack_limit, "StackGuard::address_of_real_jslimit()") \ |
41 | V(store_buffer_top, "store_buffer_top") \ |
42 | V(heap_is_marking_flag_address, "heap_is_marking_flag_address") \ |
43 | V(new_space_allocation_top_address, "Heap::NewSpaceAllocationTopAddress()") \ |
44 | V(new_space_allocation_limit_address, \ |
45 | "Heap::NewSpaceAllocationLimitAddress()") \ |
46 | V(old_space_allocation_top_address, "Heap::OldSpaceAllocationTopAddress") \ |
47 | V(old_space_allocation_limit_address, \ |
48 | "Heap::OldSpaceAllocationLimitAddress") \ |
49 | V(handle_scope_level_address, "HandleScope::level") \ |
50 | V(handle_scope_next_address, "HandleScope::next") \ |
51 | V(handle_scope_limit_address, "HandleScope::limit") \ |
52 | V(scheduled_exception_address, "Isolate::scheduled_exception") \ |
53 | V(address_of_pending_message_obj, "address_of_pending_message_obj") \ |
54 | V(promise_hook_address, "Isolate::promise_hook_address()") \ |
55 | V(async_event_delegate_address, "Isolate::async_event_delegate_address()") \ |
56 | V(promise_hook_or_async_event_delegate_address, \ |
57 | "Isolate::promise_hook_or_async_event_delegate_address()") \ |
58 | V(promise_hook_or_debug_is_active_or_async_event_delegate_address, \ |
59 | "Isolate::promise_hook_or_debug_is_active_or_async_event_delegate_" \ |
60 | "address()") \ |
61 | V(debug_execution_mode_address, "Isolate::debug_execution_mode_address()") \ |
62 | V(debug_is_active_address, "Debug::is_active_address()") \ |
63 | V(debug_hook_on_function_call_address, \ |
64 | "Debug::hook_on_function_call_address()") \ |
65 | V(runtime_function_table_address, \ |
66 | "Runtime::runtime_function_table_address()") \ |
67 | V(is_profiling_address, "Isolate::is_profiling") \ |
68 | V(debug_suspended_generator_address, \ |
69 | "Debug::step_suspended_generator_address()") \ |
70 | V(debug_restart_fp_address, "Debug::restart_fp_address()") \ |
71 | V(fast_c_call_caller_fp_address, \ |
72 | "IsolateData::fast_c_call_caller_fp_address") \ |
73 | V(fast_c_call_caller_pc_address, \ |
74 | "IsolateData::fast_c_call_caller_pc_address") \ |
75 | V(address_of_regexp_stack_limit, "RegExpStack::limit_address()") \ |
76 | V(address_of_regexp_stack_memory_address, "RegExpStack::memory_address()") \ |
77 | V(address_of_regexp_stack_memory_size, "RegExpStack::memory_size()") \ |
78 | V(address_of_static_offsets_vector, "OffsetsVector::static_offsets_vector") \ |
79 | V(re_case_insensitive_compare_uc16, \ |
80 | "NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16()") \ |
81 | V(re_check_stack_guard_state, \ |
82 | "RegExpMacroAssembler*::CheckStackGuardState()") \ |
83 | V(re_grow_stack, "NativeRegExpMacroAssembler::GrowStack()") \ |
84 | V(re_word_character_map, "NativeRegExpMacroAssembler::word_character_map") |
85 | |
86 | #define EXTERNAL_REFERENCE_LIST(V) \ |
87 | V(abort_with_reason, "abort_with_reason") \ |
88 | V(address_of_double_abs_constant, "double_absolute_constant") \ |
89 | V(address_of_double_neg_constant, "double_negate_constant") \ |
90 | V(address_of_float_abs_constant, "float_absolute_constant") \ |
91 | V(address_of_float_neg_constant, "float_negate_constant") \ |
92 | V(address_of_harmony_await_optimization_flag, \ |
93 | "FLAG_harmony_await_optimization") \ |
94 | V(address_of_min_int, "LDoubleConstant::min_int") \ |
95 | V(address_of_mock_arraybuffer_allocator_flag, \ |
96 | "FLAG_mock_arraybuffer_allocator") \ |
97 | V(address_of_one_half, "LDoubleConstant::one_half") \ |
98 | V(address_of_runtime_stats_flag, "TracingFlags::runtime_stats") \ |
99 | V(address_of_the_hole_nan, "the_hole_nan") \ |
100 | V(address_of_uint32_bias, "uint32_bias") \ |
101 | V(bytecode_size_table_address, "Bytecodes::bytecode_size_table_address") \ |
102 | V(check_object_type, "check_object_type") \ |
103 | V(compute_integer_hash, "ComputeSeededHash") \ |
104 | V(compute_output_frames_function, "Deoptimizer::ComputeOutputFrames()") \ |
105 | V(copy_fast_number_jsarray_elements_to_typed_array, \ |
106 | "copy_fast_number_jsarray_elements_to_typed_array") \ |
107 | V(copy_typed_array_elements_slice, "copy_typed_array_elements_slice") \ |
108 | V(copy_typed_array_elements_to_typed_array, \ |
109 | "copy_typed_array_elements_to_typed_array") \ |
110 | V(cpu_features, "cpu_features") \ |
111 | V(delete_handle_scope_extensions, "HandleScope::DeleteExtensions") \ |
112 | V(ephemeron_key_write_barrier_function, \ |
113 | "Heap::EphemeronKeyWriteBarrierFromCode") \ |
114 | V(f64_acos_wrapper_function, "f64_acos_wrapper") \ |
115 | V(f64_asin_wrapper_function, "f64_asin_wrapper") \ |
116 | V(f64_mod_wrapper_function, "f64_mod_wrapper") \ |
117 | V(get_date_field_function, "JSDate::GetField") \ |
118 | V(get_or_create_hash_raw, "get_or_create_hash_raw") \ |
119 | V(ieee754_acos_function, "base::ieee754::acos") \ |
120 | V(ieee754_acosh_function, "base::ieee754::acosh") \ |
121 | V(ieee754_asin_function, "base::ieee754::asin") \ |
122 | V(ieee754_asinh_function, "base::ieee754::asinh") \ |
123 | V(ieee754_atan_function, "base::ieee754::atan") \ |
124 | V(ieee754_atan2_function, "base::ieee754::atan2") \ |
125 | V(ieee754_atanh_function, "base::ieee754::atanh") \ |
126 | V(ieee754_cbrt_function, "base::ieee754::cbrt") \ |
127 | V(ieee754_cos_function, "base::ieee754::cos") \ |
128 | V(ieee754_cosh_function, "base::ieee754::cosh") \ |
129 | V(ieee754_exp_function, "base::ieee754::exp") \ |
130 | V(ieee754_expm1_function, "base::ieee754::expm1") \ |
131 | V(ieee754_log_function, "base::ieee754::log") \ |
132 | V(ieee754_log10_function, "base::ieee754::log10") \ |
133 | V(ieee754_log1p_function, "base::ieee754::log1p") \ |
134 | V(ieee754_log2_function, "base::ieee754::log2") \ |
135 | V(ieee754_pow_function, "base::ieee754::pow") \ |
136 | V(ieee754_sin_function, "base::ieee754::sin") \ |
137 | V(ieee754_sinh_function, "base::ieee754::sinh") \ |
138 | V(ieee754_tan_function, "base::ieee754::tan") \ |
139 | V(ieee754_tanh_function, "base::ieee754::tanh") \ |
140 | V(incremental_marking_record_write_function, \ |
141 | "IncrementalMarking::RecordWrite") \ |
142 | V(invalidate_prototype_chains_function, \ |
143 | "JSObject::InvalidatePrototypeChains()") \ |
144 | V(invoke_accessor_getter_callback, "InvokeAccessorGetterCallback") \ |
145 | V(invoke_function_callback, "InvokeFunctionCallback") \ |
146 | V(jsarray_array_join_concat_to_sequential_string, \ |
147 | "jsarray_array_join_concat_to_sequential_string") \ |
148 | V(jsreceiver_create_identity_hash, "jsreceiver_create_identity_hash") \ |
149 | V(libc_memchr_function, "libc_memchr") \ |
150 | V(libc_memcpy_function, "libc_memcpy") \ |
151 | V(libc_memmove_function, "libc_memmove") \ |
152 | V(libc_memset_function, "libc_memset") \ |
153 | V(log_enter_external_function, "Logger::EnterExternal") \ |
154 | V(log_leave_external_function, "Logger::LeaveExternal") \ |
155 | V(mod_two_doubles_operation, "mod_two_doubles") \ |
156 | V(new_deoptimizer_function, "Deoptimizer::New()") \ |
157 | V(orderedhashmap_gethash_raw, "orderedhashmap_gethash_raw") \ |
158 | V(printf_function, "printf") \ |
159 | V(refill_math_random, "MathRandom::RefillCache") \ |
160 | V(search_string_raw_one_one, "search_string_raw_one_one") \ |
161 | V(search_string_raw_one_two, "search_string_raw_one_two") \ |
162 | V(search_string_raw_two_one, "search_string_raw_two_one") \ |
163 | V(search_string_raw_two_two, "search_string_raw_two_two") \ |
164 | V(smi_lexicographic_compare_function, "smi_lexicographic_compare_function") \ |
165 | V(store_buffer_overflow_function, "StoreBuffer::StoreBufferOverflow") \ |
166 | V(try_internalize_string_function, "try_internalize_string_function") \ |
167 | V(wasm_call_trap_callback_for_testing, \ |
168 | "wasm::call_trap_callback_for_testing") \ |
169 | V(wasm_f32_ceil, "wasm::f32_ceil_wrapper") \ |
170 | V(wasm_f32_floor, "wasm::f32_floor_wrapper") \ |
171 | V(wasm_f32_nearest_int, "wasm::f32_nearest_int_wrapper") \ |
172 | V(wasm_f32_trunc, "wasm::f32_trunc_wrapper") \ |
173 | V(wasm_f64_ceil, "wasm::f64_ceil_wrapper") \ |
174 | V(wasm_f64_floor, "wasm::f64_floor_wrapper") \ |
175 | V(wasm_f64_nearest_int, "wasm::f64_nearest_int_wrapper") \ |
176 | V(wasm_f64_trunc, "wasm::f64_trunc_wrapper") \ |
177 | V(wasm_float32_to_int64, "wasm::float32_to_int64_wrapper") \ |
178 | V(wasm_float32_to_uint64, "wasm::float32_to_uint64_wrapper") \ |
179 | V(wasm_float64_pow, "wasm::float64_pow") \ |
180 | V(wasm_float64_to_int64, "wasm::float64_to_int64_wrapper") \ |
181 | V(wasm_float64_to_uint64, "wasm::float64_to_uint64_wrapper") \ |
182 | V(wasm_int64_div, "wasm::int64_div") \ |
183 | V(wasm_int64_mod, "wasm::int64_mod") \ |
184 | V(wasm_int64_to_float32, "wasm::int64_to_float32_wrapper") \ |
185 | V(wasm_int64_to_float64, "wasm::int64_to_float64_wrapper") \ |
186 | V(wasm_uint64_div, "wasm::uint64_div") \ |
187 | V(wasm_uint64_mod, "wasm::uint64_mod") \ |
188 | V(wasm_uint64_to_float32, "wasm::uint64_to_float32_wrapper") \ |
189 | V(wasm_uint64_to_float64, "wasm::uint64_to_float64_wrapper") \ |
190 | V(wasm_word32_ctz, "wasm::word32_ctz") \ |
191 | V(wasm_word32_popcnt, "wasm::word32_popcnt") \ |
192 | V(wasm_word32_rol, "wasm::word32_rol") \ |
193 | V(wasm_word32_ror, "wasm::word32_ror") \ |
194 | V(wasm_word64_ctz, "wasm::word64_ctz") \ |
195 | V(wasm_word64_popcnt, "wasm::word64_popcnt") \ |
196 | V(wasm_memory_copy, "wasm::memory_copy") \ |
197 | V(wasm_memory_fill, "wasm::memory_fill") \ |
198 | V(call_enqueue_microtask_function, "MicrotaskQueue::CallEnqueueMicrotask") \ |
199 | V(call_enter_context_function, "call_enter_context_function") \ |
200 | V(atomic_pair_load_function, "atomic_pair_load_function") \ |
201 | V(atomic_pair_store_function, "atomic_pair_store_function") \ |
202 | V(atomic_pair_add_function, "atomic_pair_add_function") \ |
203 | V(atomic_pair_sub_function, "atomic_pair_sub_function") \ |
204 | V(atomic_pair_and_function, "atomic_pair_and_function") \ |
205 | V(atomic_pair_or_function, "atomic_pair_or_function") \ |
206 | V(atomic_pair_xor_function, "atomic_pair_xor_function") \ |
207 | V(atomic_pair_exchange_function, "atomic_pair_exchange_function") \ |
208 | V(atomic_pair_compare_exchange_function, \ |
209 | "atomic_pair_compare_exchange_function") \ |
210 | EXTERNAL_REFERENCE_LIST_INTL(V) |
211 | |
212 | #ifdef V8_INTL_SUPPORT |
213 | #define EXTERNAL_REFERENCE_LIST_INTL(V) \ |
214 | V(intl_convert_one_byte_to_lower, "intl_convert_one_byte_to_lower") \ |
215 | V(intl_to_latin1_lower_table, "intl_to_latin1_lower_table") |
216 | #else |
217 | #define EXTERNAL_REFERENCE_LIST_INTL(V) |
218 | #endif // V8_INTL_SUPPORT |
219 | |
220 | // An ExternalReference represents a C++ address used in the generated |
221 | // code. All references to C++ functions and variables must be encapsulated |
222 | // in an ExternalReference instance. This is done in order to track the |
223 | // origin of all external references in the code so that they can be bound |
224 | // to the correct addresses when deserializing a heap. |
225 | class ExternalReference { |
226 | public: |
227 | // Used in the simulator to support different native api calls. |
228 | enum Type { |
229 | // Builtin call. |
230 | // Address f(v8::internal::Arguments). |
231 | BUILTIN_CALL, // default |
232 | |
233 | // Builtin call returning object pair. |
234 | // ObjectPair f(v8::internal::Arguments). |
235 | BUILTIN_CALL_PAIR, |
236 | |
237 | // Builtin that takes float arguments and returns an int. |
238 | // int f(double, double). |
239 | BUILTIN_COMPARE_CALL, |
240 | |
241 | // Builtin call that returns floating point. |
242 | // double f(double, double). |
243 | BUILTIN_FP_FP_CALL, |
244 | |
245 | // Builtin call that returns floating point. |
246 | // double f(double). |
247 | BUILTIN_FP_CALL, |
248 | |
249 | // Builtin call that returns floating point. |
250 | // double f(double, int). |
251 | BUILTIN_FP_INT_CALL, |
252 | |
253 | // Direct call to API function callback. |
254 | // void f(v8::FunctionCallbackInfo&) |
255 | DIRECT_API_CALL, |
256 | |
257 | // Call to function callback via InvokeFunctionCallback. |
258 | // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback) |
259 | PROFILING_API_CALL, |
260 | |
261 | // Direct call to accessor getter callback. |
262 | // void f(Local<Name> property, PropertyCallbackInfo& info) |
263 | DIRECT_GETTER_CALL, |
264 | |
265 | // Call to accessor getter callback via InvokeAccessorGetterCallback. |
266 | // void f(Local<Name> property, PropertyCallbackInfo& info, |
267 | // AccessorNameGetterCallback callback) |
268 | PROFILING_GETTER_CALL |
269 | }; |
270 | |
271 | static constexpr int kExternalReferenceCount = |
272 | #define COUNT_EXTERNAL_REFERENCE(name, desc) +1 |
273 | EXTERNAL_REFERENCE_LIST(COUNT_EXTERNAL_REFERENCE) |
274 | EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(COUNT_EXTERNAL_REFERENCE); |
275 | #undef COUNT_EXTERNAL_REFERENCE |
276 | |
277 | typedef Address ExternalReferenceRedirector(Address original, Type type); |
278 | |
279 | ExternalReference() : address_(kNullAddress) {} |
280 | static ExternalReference Create(const SCTableReference& table_ref); |
281 | static ExternalReference Create(StatsCounter* counter); |
282 | static ExternalReference Create(ApiFunction* ptr, Type type); |
283 | static ExternalReference Create(const Runtime::Function* f); |
284 | static ExternalReference Create(IsolateAddressId id, Isolate* isolate); |
285 | static ExternalReference Create(Runtime::FunctionId id); |
286 | static V8_EXPORT_PRIVATE ExternalReference Create(Address address); |
287 | |
288 | template <typename SubjectChar, typename PatternChar> |
289 | static ExternalReference search_string_raw(); |
290 | |
291 | V8_EXPORT_PRIVATE static ExternalReference FromRawAddress(Address address); |
292 | |
293 | #define DECL_EXTERNAL_REFERENCE(name, desc) \ |
294 | V8_EXPORT_PRIVATE static ExternalReference name(); |
295 | EXTERNAL_REFERENCE_LIST(DECL_EXTERNAL_REFERENCE) |
296 | #undef DECL_EXTERNAL_REFERENCE |
297 | |
298 | #define DECL_EXTERNAL_REFERENCE(name, desc) \ |
299 | static V8_EXPORT_PRIVATE ExternalReference name(Isolate* isolate); |
300 | EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(DECL_EXTERNAL_REFERENCE) |
301 | #undef DECL_EXTERNAL_REFERENCE |
302 | |
303 | V8_EXPORT_PRIVATE V8_NOINLINE static ExternalReference |
304 | runtime_function_table_address_for_unittests(Isolate* isolate); |
305 | |
306 | Address address() const { return address_; } |
307 | |
308 | private: |
309 | explicit ExternalReference(Address address) : address_(address) {} |
310 | |
311 | explicit ExternalReference(void* address) |
312 | : address_(reinterpret_cast<Address>(address)) {} |
313 | |
314 | static Address Redirect(Address address_arg, |
315 | Type type = ExternalReference::BUILTIN_CALL); |
316 | |
317 | Address address_; |
318 | }; |
319 | ASSERT_TRIVIALLY_COPYABLE(ExternalReference); |
320 | |
321 | V8_EXPORT_PRIVATE bool operator==(ExternalReference, ExternalReference); |
322 | bool operator!=(ExternalReference, ExternalReference); |
323 | |
324 | size_t hash_value(ExternalReference); |
325 | |
326 | V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ExternalReference); |
327 | |
328 | void abort_with_reason(int reason); |
329 | |
330 | } // namespace internal |
331 | } // namespace v8 |
332 | |
333 | #endif // V8_EXTERNAL_REFERENCE_H_ |
334 | |