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 #include "src/codegen/external-reference.h"
6 
7 #include "src/api/api.h"
8 #include "src/base/ieee754.h"
9 #include "src/codegen/cpu-features.h"
10 #include "src/compiler/code-assembler.h"
11 #include "src/date/date.h"
12 #include "src/debug/debug.h"
13 #include "src/deoptimizer/deoptimizer.h"
14 #include "src/execution/isolate.h"
15 #include "src/execution/microtask-queue.h"
16 #include "src/execution/simulator-base.h"
17 #include "src/heap/heap-inl.h"
18 #include "src/heap/heap.h"
19 #include "src/ic/stub-cache.h"
20 #include "src/interpreter/interpreter.h"
21 #include "src/logging/counters.h"
22 #include "src/logging/log.h"
23 #include "src/numbers/hash-seed-inl.h"
24 #include "src/numbers/math-random.h"
25 #include "src/objects/elements.h"
26 #include "src/objects/objects-inl.h"
27 #include "src/objects/ordered-hash-table.h"
28 #include "src/regexp/experimental/experimental.h"
29 #include "src/regexp/regexp-interpreter.h"
30 #include "src/regexp/regexp-macro-assembler-arch.h"
31 #include "src/regexp/regexp-stack.h"
32 #include "src/strings/string-search.h"
33 #include "src/wasm/wasm-external-refs.h"
34 
35 #ifdef V8_INTL_SUPPORT
36 #include "src/objects/intl-objects.h"
37 #endif  // V8_INTL_SUPPORT
38 
39 namespace v8 {
40 namespace internal {
41 
42 // -----------------------------------------------------------------------------
43 // Common double constants.
44 
45 constexpr double double_min_int_constant = kMinInt;
46 constexpr double double_one_half_constant = 0.5;
47 constexpr uint64_t double_the_hole_nan_constant = kHoleNanInt64;
48 constexpr double double_uint32_bias_constant =
49     static_cast<double>(kMaxUInt32) + 1;
50 
51 constexpr struct alignas(16) {
52   uint32_t a;
53   uint32_t b;
54   uint32_t c;
55   uint32_t d;
56 } float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
57 
58 constexpr struct alignas(16) {
59   uint32_t a;
60   uint32_t b;
61   uint32_t c;
62   uint32_t d;
63 } float_negate_constant = {0x80000000, 0x80000000, 0x80000000, 0x80000000};
64 
65 constexpr struct alignas(16) {
66   uint64_t a;
67   uint64_t b;
68 } double_absolute_constant = {uint64_t{0x7FFFFFFFFFFFFFFF},
69                               uint64_t{0x7FFFFFFFFFFFFFFF}};
70 
71 constexpr struct alignas(16) {
72   uint64_t a;
73   uint64_t b;
74 } double_negate_constant = {uint64_t{0x8000000000000000},
75                             uint64_t{0x8000000000000000}};
76 
77 // Implementation of ExternalReference
78 
BuiltinCallTypeForResultSize(int result_size)79 static ExternalReference::Type BuiltinCallTypeForResultSize(int result_size) {
80   switch (result_size) {
81     case 1:
82       return ExternalReference::BUILTIN_CALL;
83     case 2:
84       return ExternalReference::BUILTIN_CALL_PAIR;
85   }
86   UNREACHABLE();
87 }
88 
89 // static
Create(ApiFunction * fun,Type type=ExternalReference::BUILTIN_CALL)90 ExternalReference ExternalReference::Create(
91     ApiFunction* fun, Type type = ExternalReference::BUILTIN_CALL) {
92   return ExternalReference(Redirect(fun->address(), type));
93 }
94 
95 // static
Create(Runtime::FunctionId id)96 ExternalReference ExternalReference::Create(Runtime::FunctionId id) {
97   return Create(Runtime::FunctionForId(id));
98 }
99 
100 // static
Create(const Runtime::Function * f)101 ExternalReference ExternalReference::Create(const Runtime::Function* f) {
102   return ExternalReference(
103       Redirect(f->entry, BuiltinCallTypeForResultSize(f->result_size)));
104 }
105 
106 // static
Create(Address address)107 ExternalReference ExternalReference::Create(Address address) {
108   return ExternalReference(Redirect(address));
109 }
110 
isolate_address(Isolate * isolate)111 ExternalReference ExternalReference::isolate_address(Isolate* isolate) {
112   return ExternalReference(isolate);
113 }
114 
builtins_address(Isolate * isolate)115 ExternalReference ExternalReference::builtins_address(Isolate* isolate) {
116   return ExternalReference(isolate->heap()->builtin_address(0));
117 }
118 
handle_scope_implementer_address(Isolate * isolate)119 ExternalReference ExternalReference::handle_scope_implementer_address(
120     Isolate* isolate) {
121   return ExternalReference(isolate->handle_scope_implementer_address());
122 }
123 
124 #ifdef V8_HEAP_SANDBOX
external_pointer_table_address(Isolate * isolate)125 ExternalReference ExternalReference::external_pointer_table_address(
126     Isolate* isolate) {
127   return ExternalReference(isolate->external_pointer_table_address());
128 }
129 #endif
130 
interpreter_dispatch_table_address(Isolate * isolate)131 ExternalReference ExternalReference::interpreter_dispatch_table_address(
132     Isolate* isolate) {
133   return ExternalReference(isolate->interpreter()->dispatch_table_address());
134 }
135 
interpreter_dispatch_counters(Isolate * isolate)136 ExternalReference ExternalReference::interpreter_dispatch_counters(
137     Isolate* isolate) {
138   return ExternalReference(
139       isolate->interpreter()->bytecode_dispatch_counters_table());
140 }
141 
142 ExternalReference
address_of_interpreter_entry_trampoline_instruction_start(Isolate * isolate)143 ExternalReference::address_of_interpreter_entry_trampoline_instruction_start(
144     Isolate* isolate) {
145   return ExternalReference(
146       isolate->interpreter()
147           ->address_of_interpreter_entry_trampoline_instruction_start());
148 }
149 
bytecode_size_table_address()150 ExternalReference ExternalReference::bytecode_size_table_address() {
151   return ExternalReference(
152       interpreter::Bytecodes::bytecode_size_table_address());
153 }
154 
155 // static
Create(StatsCounter * counter)156 ExternalReference ExternalReference::Create(StatsCounter* counter) {
157   return ExternalReference(
158       reinterpret_cast<Address>(counter->GetInternalPointer()));
159 }
160 
161 // static
Create(IsolateAddressId id,Isolate * isolate)162 ExternalReference ExternalReference::Create(IsolateAddressId id,
163                                             Isolate* isolate) {
164   return ExternalReference(isolate->get_address_from_id(id));
165 }
166 
167 // static
Create(const SCTableReference & table_ref)168 ExternalReference ExternalReference::Create(const SCTableReference& table_ref) {
169   return ExternalReference(table_ref.address());
170 }
171 
172 namespace {
173 
174 // Helper function to verify that all types in a list of types are scalar.
175 // This includes primitive types (int, Address) and pointer types. We also
176 // allow void.
177 template <typename T>
AllScalar()178 constexpr bool AllScalar() {
179   return std::is_scalar<T>::value || std::is_void<T>::value;
180 }
181 
182 template <typename T1, typename T2, typename... Rest>
AllScalar()183 constexpr bool AllScalar() {
184   return AllScalar<T1>() && AllScalar<T2, Rest...>();
185 }
186 
187 // Checks a function pointer's type for compatibility with the
188 // ExternalReference calling mechanism. Specifically, all arguments
189 // as well as the result type must pass the AllScalar check above,
190 // because we expect each item to fit into one register or stack slot.
191 template <typename T>
192 struct IsValidExternalReferenceType;
193 
194 template <typename Result, typename... Args>
195 struct IsValidExternalReferenceType<Result (*)(Args...)> {
196   static const bool value = AllScalar<Result, Args...>();
197 };
198 
199 template <typename Result, typename Class, typename... Args>
200 struct IsValidExternalReferenceType<Result (Class::*)(Args...)> {
201   static const bool value = AllScalar<Result, Args...>();
202 };
203 
204 }  // namespace
205 
206 #define FUNCTION_REFERENCE(Name, Target)                                   \
207   ExternalReference ExternalReference::Name() {                            \
208     STATIC_ASSERT(IsValidExternalReferenceType<decltype(&Target)>::value); \
209     return ExternalReference(Redirect(FUNCTION_ADDR(Target)));             \
210   }
211 
212 #define FUNCTION_REFERENCE_WITH_ISOLATE(Name, Target)                      \
213   ExternalReference ExternalReference::Name(Isolate* isolate) {            \
214     STATIC_ASSERT(IsValidExternalReferenceType<decltype(&Target)>::value); \
215     return ExternalReference(Redirect(FUNCTION_ADDR(Target)));             \
216   }
217 
218 #define FUNCTION_REFERENCE_WITH_TYPE(Name, Target, Type)                   \
219   ExternalReference ExternalReference::Name() {                            \
220     STATIC_ASSERT(IsValidExternalReferenceType<decltype(&Target)>::value); \
221     return ExternalReference(Redirect(FUNCTION_ADDR(Target), Type));       \
222   }
223 
FUNCTION_REFERENCE(write_barrier_marking_from_code_function,WriteBarrier::MarkingFromCode)224 FUNCTION_REFERENCE(write_barrier_marking_from_code_function,
225                    WriteBarrier::MarkingFromCode)
226 
227 FUNCTION_REFERENCE(insert_remembered_set_function,
228                    Heap::InsertIntoRememberedSetFromCode)
229 
230 FUNCTION_REFERENCE(delete_handle_scope_extensions,
231                    HandleScope::DeleteExtensions)
232 
233 FUNCTION_REFERENCE(ephemeron_key_write_barrier_function,
234                    Heap::EphemeronKeyWriteBarrierFromCode)
235 
236 FUNCTION_REFERENCE(get_date_field_function, JSDate::GetField)
237 
238 ExternalReference ExternalReference::date_cache_stamp(Isolate* isolate) {
239   return ExternalReference(isolate->date_cache()->stamp_address());
240 }
241 
242 // static
243 ExternalReference
runtime_function_table_address_for_unittests(Isolate * isolate)244 ExternalReference::runtime_function_table_address_for_unittests(
245     Isolate* isolate) {
246   return runtime_function_table_address(isolate);
247 }
248 
249 // static
Redirect(Address address,Type type)250 Address ExternalReference::Redirect(Address address, Type type) {
251 #ifdef USE_SIMULATOR
252   return SimulatorBase::RedirectExternalReference(address, type);
253 #else
254   return address;
255 #endif
256 }
257 
stress_deopt_count(Isolate * isolate)258 ExternalReference ExternalReference::stress_deopt_count(Isolate* isolate) {
259   return ExternalReference(isolate->stress_deopt_count_address());
260 }
261 
force_slow_path(Isolate * isolate)262 ExternalReference ExternalReference::force_slow_path(Isolate* isolate) {
263   return ExternalReference(isolate->force_slow_path_address());
264 }
265 
FUNCTION_REFERENCE(new_deoptimizer_function,Deoptimizer::New)266 FUNCTION_REFERENCE(new_deoptimizer_function, Deoptimizer::New)
267 
268 FUNCTION_REFERENCE(compute_output_frames_function,
269                    Deoptimizer::ComputeOutputFrames)
270 
271 FUNCTION_REFERENCE(wasm_f32_trunc, wasm::f32_trunc_wrapper)
272 FUNCTION_REFERENCE(wasm_f32_floor, wasm::f32_floor_wrapper)
273 FUNCTION_REFERENCE(wasm_f32_ceil, wasm::f32_ceil_wrapper)
274 FUNCTION_REFERENCE(wasm_f32_nearest_int, wasm::f32_nearest_int_wrapper)
275 FUNCTION_REFERENCE(wasm_f64_trunc, wasm::f64_trunc_wrapper)
276 FUNCTION_REFERENCE(wasm_f64_floor, wasm::f64_floor_wrapper)
277 FUNCTION_REFERENCE(wasm_f64_ceil, wasm::f64_ceil_wrapper)
278 FUNCTION_REFERENCE(wasm_f64_nearest_int, wasm::f64_nearest_int_wrapper)
279 FUNCTION_REFERENCE(wasm_int64_to_float32, wasm::int64_to_float32_wrapper)
280 FUNCTION_REFERENCE(wasm_uint64_to_float32, wasm::uint64_to_float32_wrapper)
281 FUNCTION_REFERENCE(wasm_int64_to_float64, wasm::int64_to_float64_wrapper)
282 FUNCTION_REFERENCE(wasm_uint64_to_float64, wasm::uint64_to_float64_wrapper)
283 FUNCTION_REFERENCE(wasm_float32_to_int64, wasm::float32_to_int64_wrapper)
284 FUNCTION_REFERENCE(wasm_float32_to_uint64, wasm::float32_to_uint64_wrapper)
285 FUNCTION_REFERENCE(wasm_float64_to_int64, wasm::float64_to_int64_wrapper)
286 FUNCTION_REFERENCE(wasm_float64_to_uint64, wasm::float64_to_uint64_wrapper)
287 FUNCTION_REFERENCE(wasm_float32_to_int64_sat,
288                    wasm::float32_to_int64_sat_wrapper)
289 FUNCTION_REFERENCE(wasm_float32_to_uint64_sat,
290                    wasm::float32_to_uint64_sat_wrapper)
291 FUNCTION_REFERENCE(wasm_float64_to_int64_sat,
292                    wasm::float64_to_int64_sat_wrapper)
293 FUNCTION_REFERENCE(wasm_float64_to_uint64_sat,
294                    wasm::float64_to_uint64_sat_wrapper)
295 FUNCTION_REFERENCE(wasm_int64_div, wasm::int64_div_wrapper)
296 FUNCTION_REFERENCE(wasm_int64_mod, wasm::int64_mod_wrapper)
297 FUNCTION_REFERENCE(wasm_uint64_div, wasm::uint64_div_wrapper)
298 FUNCTION_REFERENCE(wasm_uint64_mod, wasm::uint64_mod_wrapper)
299 FUNCTION_REFERENCE(wasm_word32_ctz, wasm::word32_ctz_wrapper)
300 FUNCTION_REFERENCE(wasm_word64_ctz, wasm::word64_ctz_wrapper)
301 FUNCTION_REFERENCE(wasm_word32_popcnt, wasm::word32_popcnt_wrapper)
302 FUNCTION_REFERENCE(wasm_word64_popcnt, wasm::word64_popcnt_wrapper)
303 FUNCTION_REFERENCE(wasm_word32_rol, wasm::word32_rol_wrapper)
304 FUNCTION_REFERENCE(wasm_word32_ror, wasm::word32_ror_wrapper)
305 FUNCTION_REFERENCE(wasm_word64_rol, wasm::word64_rol_wrapper)
306 FUNCTION_REFERENCE(wasm_word64_ror, wasm::word64_ror_wrapper)
307 FUNCTION_REFERENCE(wasm_f64x2_ceil, wasm::f64x2_ceil_wrapper)
308 FUNCTION_REFERENCE(wasm_f64x2_floor, wasm::f64x2_floor_wrapper)
309 FUNCTION_REFERENCE(wasm_f64x2_trunc, wasm::f64x2_trunc_wrapper)
310 FUNCTION_REFERENCE(wasm_f64x2_nearest_int, wasm::f64x2_nearest_int_wrapper)
311 FUNCTION_REFERENCE(wasm_f32x4_ceil, wasm::f32x4_ceil_wrapper)
312 FUNCTION_REFERENCE(wasm_f32x4_floor, wasm::f32x4_floor_wrapper)
313 FUNCTION_REFERENCE(wasm_f32x4_trunc, wasm::f32x4_trunc_wrapper)
314 FUNCTION_REFERENCE(wasm_f32x4_nearest_int, wasm::f32x4_nearest_int_wrapper)
315 FUNCTION_REFERENCE(wasm_memory_init, wasm::memory_init_wrapper)
316 FUNCTION_REFERENCE(wasm_memory_copy, wasm::memory_copy_wrapper)
317 FUNCTION_REFERENCE(wasm_memory_fill, wasm::memory_fill_wrapper)
318 
319 static void f64_acos_wrapper(Address data) {
320   double input = ReadUnalignedValue<double>(data);
321   WriteUnalignedValue(data, base::ieee754::acos(input));
322 }
323 
FUNCTION_REFERENCE(f64_acos_wrapper_function,f64_acos_wrapper)324 FUNCTION_REFERENCE(f64_acos_wrapper_function, f64_acos_wrapper)
325 
326 static void f64_asin_wrapper(Address data) {
327   double input = ReadUnalignedValue<double>(data);
328   WriteUnalignedValue<double>(data, base::ieee754::asin(input));
329 }
330 
FUNCTION_REFERENCE(f64_asin_wrapper_function,f64_asin_wrapper)331 FUNCTION_REFERENCE(f64_asin_wrapper_function, f64_asin_wrapper)
332 
333 FUNCTION_REFERENCE(wasm_float64_pow, wasm::float64_pow_wrapper)
334 
335 static void f64_mod_wrapper(Address data) {
336   double dividend = ReadUnalignedValue<double>(data);
337   double divisor = ReadUnalignedValue<double>(data + sizeof(dividend));
338   WriteUnalignedValue<double>(data, Modulo(dividend, divisor));
339 }
340 
FUNCTION_REFERENCE(f64_mod_wrapper_function,f64_mod_wrapper)341 FUNCTION_REFERENCE(f64_mod_wrapper_function, f64_mod_wrapper)
342 
343 FUNCTION_REFERENCE(wasm_call_trap_callback_for_testing,
344                    wasm::call_trap_callback_for_testing)
345 
346 ExternalReference ExternalReference::isolate_root(Isolate* isolate) {
347   return ExternalReference(isolate->isolate_root());
348 }
349 
allocation_sites_list_address(Isolate * isolate)350 ExternalReference ExternalReference::allocation_sites_list_address(
351     Isolate* isolate) {
352   return ExternalReference(isolate->heap()->allocation_sites_list_address());
353 }
354 
address_of_jslimit(Isolate * isolate)355 ExternalReference ExternalReference::address_of_jslimit(Isolate* isolate) {
356   Address address = isolate->stack_guard()->address_of_jslimit();
357   // For efficient generated code, this should be root-register-addressable.
358   DCHECK(isolate->root_register_addressable_region().contains(address));
359   return ExternalReference(address);
360 }
361 
address_of_real_jslimit(Isolate * isolate)362 ExternalReference ExternalReference::address_of_real_jslimit(Isolate* isolate) {
363   Address address = isolate->stack_guard()->address_of_real_jslimit();
364   // For efficient generated code, this should be root-register-addressable.
365   DCHECK(isolate->root_register_addressable_region().contains(address));
366   return ExternalReference(address);
367 }
368 
heap_is_marking_flag_address(Isolate * isolate)369 ExternalReference ExternalReference::heap_is_marking_flag_address(
370     Isolate* isolate) {
371   return ExternalReference(isolate->heap()->IsMarkingFlagAddress());
372 }
373 
new_space_allocation_top_address(Isolate * isolate)374 ExternalReference ExternalReference::new_space_allocation_top_address(
375     Isolate* isolate) {
376   return ExternalReference(isolate->heap()->NewSpaceAllocationTopAddress());
377 }
378 
new_space_allocation_limit_address(Isolate * isolate)379 ExternalReference ExternalReference::new_space_allocation_limit_address(
380     Isolate* isolate) {
381   return ExternalReference(isolate->heap()->NewSpaceAllocationLimitAddress());
382 }
383 
old_space_allocation_top_address(Isolate * isolate)384 ExternalReference ExternalReference::old_space_allocation_top_address(
385     Isolate* isolate) {
386   return ExternalReference(isolate->heap()->OldSpaceAllocationTopAddress());
387 }
388 
old_space_allocation_limit_address(Isolate * isolate)389 ExternalReference ExternalReference::old_space_allocation_limit_address(
390     Isolate* isolate) {
391   return ExternalReference(isolate->heap()->OldSpaceAllocationLimitAddress());
392 }
393 
handle_scope_level_address(Isolate * isolate)394 ExternalReference ExternalReference::handle_scope_level_address(
395     Isolate* isolate) {
396   return ExternalReference(HandleScope::current_level_address(isolate));
397 }
398 
handle_scope_next_address(Isolate * isolate)399 ExternalReference ExternalReference::handle_scope_next_address(
400     Isolate* isolate) {
401   return ExternalReference(HandleScope::current_next_address(isolate));
402 }
403 
handle_scope_limit_address(Isolate * isolate)404 ExternalReference ExternalReference::handle_scope_limit_address(
405     Isolate* isolate) {
406   return ExternalReference(HandleScope::current_limit_address(isolate));
407 }
408 
scheduled_exception_address(Isolate * isolate)409 ExternalReference ExternalReference::scheduled_exception_address(
410     Isolate* isolate) {
411   return ExternalReference(isolate->scheduled_exception_address());
412 }
413 
address_of_pending_message_obj(Isolate * isolate)414 ExternalReference ExternalReference::address_of_pending_message_obj(
415     Isolate* isolate) {
416   return ExternalReference(isolate->pending_message_obj_address());
417 }
418 
FUNCTION_REFERENCE(abort_with_reason,i::abort_with_reason)419 FUNCTION_REFERENCE(abort_with_reason, i::abort_with_reason)
420 
421 ExternalReference ExternalReference::address_of_min_int() {
422   return ExternalReference(reinterpret_cast<Address>(&double_min_int_constant));
423 }
424 
425 ExternalReference
address_of_mock_arraybuffer_allocator_flag()426 ExternalReference::address_of_mock_arraybuffer_allocator_flag() {
427   return ExternalReference(&FLAG_mock_arraybuffer_allocator);
428 }
429 
address_of_runtime_stats_flag()430 ExternalReference ExternalReference::address_of_runtime_stats_flag() {
431   return ExternalReference(&TracingFlags::runtime_stats);
432 }
433 
address_of_load_from_stack_count(const char * function_name)434 ExternalReference ExternalReference::address_of_load_from_stack_count(
435     const char* function_name) {
436   return ExternalReference(
437       Isolate::load_from_stack_count_address(function_name));
438 }
439 
address_of_store_to_stack_count(const char * function_name)440 ExternalReference ExternalReference::address_of_store_to_stack_count(
441     const char* function_name) {
442   return ExternalReference(
443       Isolate::store_to_stack_count_address(function_name));
444 }
445 
address_of_one_half()446 ExternalReference ExternalReference::address_of_one_half() {
447   return ExternalReference(
448       reinterpret_cast<Address>(&double_one_half_constant));
449 }
450 
address_of_the_hole_nan()451 ExternalReference ExternalReference::address_of_the_hole_nan() {
452   return ExternalReference(
453       reinterpret_cast<Address>(&double_the_hole_nan_constant));
454 }
455 
address_of_uint32_bias()456 ExternalReference ExternalReference::address_of_uint32_bias() {
457   return ExternalReference(
458       reinterpret_cast<Address>(&double_uint32_bias_constant));
459 }
460 
address_of_float_abs_constant()461 ExternalReference ExternalReference::address_of_float_abs_constant() {
462   return ExternalReference(reinterpret_cast<Address>(&float_absolute_constant));
463 }
464 
address_of_float_neg_constant()465 ExternalReference ExternalReference::address_of_float_neg_constant() {
466   return ExternalReference(reinterpret_cast<Address>(&float_negate_constant));
467 }
468 
address_of_double_abs_constant()469 ExternalReference ExternalReference::address_of_double_abs_constant() {
470   return ExternalReference(
471       reinterpret_cast<Address>(&double_absolute_constant));
472 }
473 
address_of_double_neg_constant()474 ExternalReference ExternalReference::address_of_double_neg_constant() {
475   return ExternalReference(reinterpret_cast<Address>(&double_negate_constant));
476 }
477 
478 ExternalReference
address_of_enable_experimental_regexp_engine()479 ExternalReference::address_of_enable_experimental_regexp_engine() {
480   return ExternalReference(&FLAG_enable_experimental_regexp_engine);
481 }
482 
is_profiling_address(Isolate * isolate)483 ExternalReference ExternalReference::is_profiling_address(Isolate* isolate) {
484   return ExternalReference(isolate->is_profiling_address());
485 }
486 
invoke_function_callback()487 ExternalReference ExternalReference::invoke_function_callback() {
488   Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
489   ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
490   ApiFunction thunk_fun(thunk_address);
491   return ExternalReference::Create(&thunk_fun, thunk_type);
492 }
493 
invoke_accessor_getter_callback()494 ExternalReference ExternalReference::invoke_accessor_getter_callback() {
495   Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
496   ExternalReference::Type thunk_type = ExternalReference::PROFILING_GETTER_CALL;
497   ApiFunction thunk_fun(thunk_address);
498   return ExternalReference::Create(&thunk_fun, thunk_type);
499 }
500 
501 #if V8_TARGET_ARCH_X64
502 #define re_stack_check_func RegExpMacroAssemblerX64::CheckStackGuardState
503 #elif V8_TARGET_ARCH_IA32
504 #define re_stack_check_func RegExpMacroAssemblerIA32::CheckStackGuardState
505 #elif V8_TARGET_ARCH_ARM64
506 #define re_stack_check_func RegExpMacroAssemblerARM64::CheckStackGuardState
507 #elif V8_TARGET_ARCH_ARM
508 #define re_stack_check_func RegExpMacroAssemblerARM::CheckStackGuardState
509 #elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
510 #define re_stack_check_func RegExpMacroAssemblerPPC::CheckStackGuardState
511 #elif V8_TARGET_ARCH_MIPS
512 #define re_stack_check_func RegExpMacroAssemblerMIPS::CheckStackGuardState
513 #elif V8_TARGET_ARCH_MIPS64
514 #define re_stack_check_func RegExpMacroAssemblerMIPS::CheckStackGuardState
515 #elif V8_TARGET_ARCH_S390
516 #define re_stack_check_func RegExpMacroAssemblerS390::CheckStackGuardState
517 #else
518 UNREACHABLE();
519 #endif
520 
FUNCTION_REFERENCE_WITH_ISOLATE(re_check_stack_guard_state,re_stack_check_func)521 FUNCTION_REFERENCE_WITH_ISOLATE(re_check_stack_guard_state, re_stack_check_func)
522 #undef re_stack_check_func
523 
524 FUNCTION_REFERENCE_WITH_ISOLATE(re_grow_stack,
525                                 NativeRegExpMacroAssembler::GrowStack)
526 
527 FUNCTION_REFERENCE(re_match_for_call_from_js,
528                    IrregexpInterpreter::MatchForCallFromJs)
529 
530 FUNCTION_REFERENCE(re_experimental_match_for_call_from_js,
531                    ExperimentalRegExp::MatchForCallFromJs)
532 
533 FUNCTION_REFERENCE_WITH_ISOLATE(
534     re_case_insensitive_compare_unicode,
535     NativeRegExpMacroAssembler::CaseInsensitiveCompareUnicode)
536 
537 FUNCTION_REFERENCE_WITH_ISOLATE(
538     re_case_insensitive_compare_non_unicode,
539     NativeRegExpMacroAssembler::CaseInsensitiveCompareNonUnicode)
540 
541 ExternalReference ExternalReference::re_word_character_map(Isolate* isolate) {
542   return ExternalReference(
543       NativeRegExpMacroAssembler::word_character_map_address());
544 }
545 
address_of_static_offsets_vector(Isolate * isolate)546 ExternalReference ExternalReference::address_of_static_offsets_vector(
547     Isolate* isolate) {
548   return ExternalReference(
549       reinterpret_cast<Address>(isolate->jsregexp_static_offsets_vector()));
550 }
551 
address_of_regexp_stack_limit_address(Isolate * isolate)552 ExternalReference ExternalReference::address_of_regexp_stack_limit_address(
553     Isolate* isolate) {
554   return ExternalReference(isolate->regexp_stack()->limit_address_address());
555 }
556 
address_of_regexp_stack_memory_top_address(Isolate * isolate)557 ExternalReference ExternalReference::address_of_regexp_stack_memory_top_address(
558     Isolate* isolate) {
559   return ExternalReference(
560       isolate->regexp_stack()->memory_top_address_address());
561 }
562 
FUNCTION_REFERENCE_WITH_TYPE(ieee754_acos_function,base::ieee754::acos,BUILTIN_FP_CALL)563 FUNCTION_REFERENCE_WITH_TYPE(ieee754_acos_function, base::ieee754::acos,
564                              BUILTIN_FP_CALL)
565 FUNCTION_REFERENCE_WITH_TYPE(ieee754_acosh_function, base::ieee754::acosh,
566                              BUILTIN_FP_CALL)
567 FUNCTION_REFERENCE_WITH_TYPE(ieee754_asin_function, base::ieee754::asin,
568                              BUILTIN_FP_CALL)
569 FUNCTION_REFERENCE_WITH_TYPE(ieee754_asinh_function, base::ieee754::asinh,
570                              BUILTIN_FP_CALL)
571 FUNCTION_REFERENCE_WITH_TYPE(ieee754_atan_function, base::ieee754::atan,
572                              BUILTIN_FP_CALL)
573 FUNCTION_REFERENCE_WITH_TYPE(ieee754_atanh_function, base::ieee754::atanh,
574                              BUILTIN_FP_CALL)
575 FUNCTION_REFERENCE_WITH_TYPE(ieee754_atan2_function, base::ieee754::atan2,
576                              BUILTIN_FP_FP_CALL)
577 FUNCTION_REFERENCE_WITH_TYPE(ieee754_cbrt_function, base::ieee754::cbrt,
578                              BUILTIN_FP_CALL)
579 FUNCTION_REFERENCE_WITH_TYPE(ieee754_cos_function, base::ieee754::cos,
580                              BUILTIN_FP_CALL)
581 FUNCTION_REFERENCE_WITH_TYPE(ieee754_cosh_function, base::ieee754::cosh,
582                              BUILTIN_FP_CALL)
583 FUNCTION_REFERENCE_WITH_TYPE(ieee754_exp_function, base::ieee754::exp,
584                              BUILTIN_FP_CALL)
585 FUNCTION_REFERENCE_WITH_TYPE(ieee754_expm1_function, base::ieee754::expm1,
586                              BUILTIN_FP_CALL)
587 FUNCTION_REFERENCE_WITH_TYPE(ieee754_log_function, base::ieee754::log,
588                              BUILTIN_FP_CALL)
589 FUNCTION_REFERENCE_WITH_TYPE(ieee754_log1p_function, base::ieee754::log1p,
590                              BUILTIN_FP_CALL)
591 FUNCTION_REFERENCE_WITH_TYPE(ieee754_log10_function, base::ieee754::log10,
592                              BUILTIN_FP_CALL)
593 FUNCTION_REFERENCE_WITH_TYPE(ieee754_log2_function, base::ieee754::log2,
594                              BUILTIN_FP_CALL)
595 FUNCTION_REFERENCE_WITH_TYPE(ieee754_sin_function, base::ieee754::sin,
596                              BUILTIN_FP_CALL)
597 FUNCTION_REFERENCE_WITH_TYPE(ieee754_sinh_function, base::ieee754::sinh,
598                              BUILTIN_FP_CALL)
599 FUNCTION_REFERENCE_WITH_TYPE(ieee754_tan_function, base::ieee754::tan,
600                              BUILTIN_FP_CALL)
601 FUNCTION_REFERENCE_WITH_TYPE(ieee754_tanh_function, base::ieee754::tanh,
602                              BUILTIN_FP_CALL)
603 FUNCTION_REFERENCE_WITH_TYPE(ieee754_pow_function, base::ieee754::pow,
604                              BUILTIN_FP_FP_CALL)
605 
606 void* libc_memchr(void* string, int character, size_t search_length) {
607   return memchr(string, character, search_length);
608 }
609 
FUNCTION_REFERENCE(libc_memchr_function,libc_memchr)610 FUNCTION_REFERENCE(libc_memchr_function, libc_memchr)
611 
612 void* libc_memcpy(void* dest, const void* src, size_t n) {
613   return memcpy(dest, src, n);
614 }
615 
FUNCTION_REFERENCE(libc_memcpy_function,libc_memcpy)616 FUNCTION_REFERENCE(libc_memcpy_function, libc_memcpy)
617 
618 void* libc_memmove(void* dest, const void* src, size_t n) {
619   return memmove(dest, src, n);
620 }
621 
FUNCTION_REFERENCE(libc_memmove_function,libc_memmove)622 FUNCTION_REFERENCE(libc_memmove_function, libc_memmove)
623 
624 void* libc_memset(void* dest, int value, size_t n) {
625   DCHECK_EQ(static_cast<byte>(value), value);
626   return memset(dest, value, n);
627 }
628 
FUNCTION_REFERENCE(libc_memset_function,libc_memset)629 FUNCTION_REFERENCE(libc_memset_function, libc_memset)
630 
631 ExternalReference ExternalReference::printf_function() {
632   return ExternalReference(Redirect(FUNCTION_ADDR(std::printf)));
633 }
634 
FUNCTION_REFERENCE(refill_math_random,MathRandom::RefillCache)635 FUNCTION_REFERENCE(refill_math_random, MathRandom::RefillCache)
636 
637 template <typename SubjectChar, typename PatternChar>
638 ExternalReference ExternalReference::search_string_raw() {
639   auto f = SearchStringRaw<SubjectChar, PatternChar>;
640   return ExternalReference(Redirect(FUNCTION_ADDR(f)));
641 }
642 
FUNCTION_REFERENCE(jsarray_array_join_concat_to_sequential_string,JSArray::ArrayJoinConcatToSequentialString)643 FUNCTION_REFERENCE(jsarray_array_join_concat_to_sequential_string,
644                    JSArray::ArrayJoinConcatToSequentialString)
645 
646 ExternalReference ExternalReference::search_string_raw_one_one() {
647   return search_string_raw<const uint8_t, const uint8_t>();
648 }
649 
search_string_raw_one_two()650 ExternalReference ExternalReference::search_string_raw_one_two() {
651   return search_string_raw<const uint8_t, const uc16>();
652 }
653 
search_string_raw_two_one()654 ExternalReference ExternalReference::search_string_raw_two_one() {
655   return search_string_raw<const uc16, const uint8_t>();
656 }
657 
search_string_raw_two_two()658 ExternalReference ExternalReference::search_string_raw_two_two() {
659   return search_string_raw<const uc16, const uc16>();
660 }
661 
FUNCTION_REFERENCE(orderedhashmap_gethash_raw,OrderedHashMap::GetHash)662 FUNCTION_REFERENCE(orderedhashmap_gethash_raw, OrderedHashMap::GetHash)
663 
664 Address GetOrCreateHash(Isolate* isolate, Address raw_key) {
665   DisallowHeapAllocation no_gc;
666   return Object(raw_key).GetOrCreateHash(isolate).ptr();
667 }
668 
FUNCTION_REFERENCE(get_or_create_hash_raw,GetOrCreateHash)669 FUNCTION_REFERENCE(get_or_create_hash_raw, GetOrCreateHash)
670 
671 static Address JSReceiverCreateIdentityHash(Isolate* isolate, Address raw_key) {
672   JSReceiver key = JSReceiver::cast(Object(raw_key));
673   return JSReceiver::CreateIdentityHash(isolate, key).ptr();
674 }
675 
FUNCTION_REFERENCE(jsreceiver_create_identity_hash,JSReceiverCreateIdentityHash)676 FUNCTION_REFERENCE(jsreceiver_create_identity_hash,
677                    JSReceiverCreateIdentityHash)
678 
679 static uint32_t ComputeSeededIntegerHash(Isolate* isolate, int32_t key) {
680   DisallowHeapAllocation no_gc;
681   return ComputeSeededHash(static_cast<uint32_t>(key), HashSeed(isolate));
682 }
683 
FUNCTION_REFERENCE(compute_integer_hash,ComputeSeededIntegerHash)684 FUNCTION_REFERENCE(compute_integer_hash, ComputeSeededIntegerHash)
685 FUNCTION_REFERENCE(copy_fast_number_jsarray_elements_to_typed_array,
686                    CopyFastNumberJSArrayElementsToTypedArray)
687 FUNCTION_REFERENCE(copy_typed_array_elements_to_typed_array,
688                    CopyTypedArrayElementsToTypedArray)
689 FUNCTION_REFERENCE(copy_typed_array_elements_slice, CopyTypedArrayElementsSlice)
690 FUNCTION_REFERENCE(try_string_to_index_or_lookup_existing,
691                    StringTable::TryStringToIndexOrLookupExisting)
692 FUNCTION_REFERENCE(string_to_array_index_function, String::ToArrayIndex)
693 
694 static Address LexicographicCompareWrapper(Isolate* isolate, Address smi_x,
695                                            Address smi_y) {
696   Smi x(smi_x);
697   Smi y(smi_y);
698   return Smi::LexicographicCompare(isolate, x, y);
699 }
700 
FUNCTION_REFERENCE(smi_lexicographic_compare_function,LexicographicCompareWrapper)701 FUNCTION_REFERENCE(smi_lexicographic_compare_function,
702                    LexicographicCompareWrapper)
703 
704 FUNCTION_REFERENCE(mutable_big_int_absolute_add_and_canonicalize_function,
705                    MutableBigInt_AbsoluteAddAndCanonicalize)
706 
707 FUNCTION_REFERENCE(mutable_big_int_absolute_compare_function,
708                    MutableBigInt_AbsoluteCompare)
709 
710 FUNCTION_REFERENCE(mutable_big_int_absolute_sub_and_canonicalize_function,
711                    MutableBigInt_AbsoluteSubAndCanonicalize)
712 
713 FUNCTION_REFERENCE(check_object_type, CheckObjectType)
714 
715 #ifdef V8_INTL_SUPPORT
716 
717 static Address ConvertOneByteToLower(Address raw_src, Address raw_dst) {
718   String src = String::cast(Object(raw_src));
719   String dst = String::cast(Object(raw_dst));
720   return Intl::ConvertOneByteToLower(src, dst).ptr();
721 }
FUNCTION_REFERENCE(intl_convert_one_byte_to_lower,ConvertOneByteToLower)722 FUNCTION_REFERENCE(intl_convert_one_byte_to_lower, ConvertOneByteToLower)
723 
724 ExternalReference ExternalReference::intl_to_latin1_lower_table() {
725   uint8_t* ptr = const_cast<uint8_t*>(Intl::ToLatin1LowerTable());
726   return ExternalReference(reinterpret_cast<Address>(ptr));
727 }
728 #endif  // V8_INTL_SUPPORT
729 
730 // Explicit instantiations for all combinations of 1- and 2-byte strings.
731 template ExternalReference
732 ExternalReference::search_string_raw<const uint8_t, const uint8_t>();
733 template ExternalReference
734 ExternalReference::search_string_raw<const uint8_t, const uc16>();
735 template ExternalReference
736 ExternalReference::search_string_raw<const uc16, const uint8_t>();
737 template ExternalReference
738 ExternalReference::search_string_raw<const uc16, const uc16>();
739 
FromRawAddress(Address address)740 ExternalReference ExternalReference::FromRawAddress(Address address) {
741   return ExternalReference(address);
742 }
743 
cpu_features()744 ExternalReference ExternalReference::cpu_features() {
745   DCHECK(CpuFeatures::initialized_);
746   return ExternalReference(&CpuFeatures::supported_);
747 }
748 
promise_hook_address(Isolate * isolate)749 ExternalReference ExternalReference::promise_hook_address(Isolate* isolate) {
750   return ExternalReference(isolate->promise_hook_address());
751 }
752 
async_event_delegate_address(Isolate * isolate)753 ExternalReference ExternalReference::async_event_delegate_address(
754     Isolate* isolate) {
755   return ExternalReference(isolate->async_event_delegate_address());
756 }
757 
758 ExternalReference
promise_hook_or_async_event_delegate_address(Isolate * isolate)759 ExternalReference::promise_hook_or_async_event_delegate_address(
760     Isolate* isolate) {
761   return ExternalReference(
762       isolate->promise_hook_or_async_event_delegate_address());
763 }
764 
765 ExternalReference ExternalReference::
promise_hook_or_debug_is_active_or_async_event_delegate_address(Isolate * isolate)766     promise_hook_or_debug_is_active_or_async_event_delegate_address(
767         Isolate* isolate) {
768   return ExternalReference(
769       isolate
770           ->promise_hook_or_debug_is_active_or_async_event_delegate_address());
771 }
772 
debug_execution_mode_address(Isolate * isolate)773 ExternalReference ExternalReference::debug_execution_mode_address(
774     Isolate* isolate) {
775   return ExternalReference(isolate->debug_execution_mode_address());
776 }
777 
debug_is_active_address(Isolate * isolate)778 ExternalReference ExternalReference::debug_is_active_address(Isolate* isolate) {
779   return ExternalReference(isolate->debug()->is_active_address());
780 }
781 
debug_hook_on_function_call_address(Isolate * isolate)782 ExternalReference ExternalReference::debug_hook_on_function_call_address(
783     Isolate* isolate) {
784   return ExternalReference(isolate->debug()->hook_on_function_call_address());
785 }
786 
runtime_function_table_address(Isolate * isolate)787 ExternalReference ExternalReference::runtime_function_table_address(
788     Isolate* isolate) {
789   return ExternalReference(
790       const_cast<Runtime::Function*>(Runtime::RuntimeFunctionTable(isolate)));
791 }
792 
InvalidatePrototypeChainsWrapper(Address raw_map)793 static Address InvalidatePrototypeChainsWrapper(Address raw_map) {
794   Map map = Map::cast(Object(raw_map));
795   return JSObject::InvalidatePrototypeChains(map).ptr();
796 }
797 
FUNCTION_REFERENCE(invalidate_prototype_chains_function,InvalidatePrototypeChainsWrapper)798 FUNCTION_REFERENCE(invalidate_prototype_chains_function,
799                    InvalidatePrototypeChainsWrapper)
800 
801 double modulo_double_double(double x, double y) { return Modulo(x, y); }
802 
FUNCTION_REFERENCE_WITH_TYPE(mod_two_doubles_operation,modulo_double_double,BUILTIN_FP_FP_CALL)803 FUNCTION_REFERENCE_WITH_TYPE(mod_two_doubles_operation, modulo_double_double,
804                              BUILTIN_FP_FP_CALL)
805 
806 ExternalReference ExternalReference::debug_suspended_generator_address(
807     Isolate* isolate) {
808   return ExternalReference(isolate->debug()->suspended_generator_address());
809 }
810 
debug_restart_fp_address(Isolate * isolate)811 ExternalReference ExternalReference::debug_restart_fp_address(
812     Isolate* isolate) {
813   return ExternalReference(isolate->debug()->restart_fp_address());
814 }
815 
fast_c_call_caller_fp_address(Isolate * isolate)816 ExternalReference ExternalReference::fast_c_call_caller_fp_address(
817     Isolate* isolate) {
818   return ExternalReference(
819       isolate->isolate_data()->fast_c_call_caller_fp_address());
820 }
821 
fast_c_call_caller_pc_address(Isolate * isolate)822 ExternalReference ExternalReference::fast_c_call_caller_pc_address(
823     Isolate* isolate) {
824   return ExternalReference(
825       isolate->isolate_data()->fast_c_call_caller_pc_address());
826 }
827 
stack_is_iterable_address(Isolate * isolate)828 ExternalReference ExternalReference::stack_is_iterable_address(
829     Isolate* isolate) {
830   return ExternalReference(
831       isolate->isolate_data()->stack_is_iterable_address());
832 }
833 
FUNCTION_REFERENCE(call_enqueue_microtask_function,MicrotaskQueue::CallEnqueueMicrotask)834 FUNCTION_REFERENCE(call_enqueue_microtask_function,
835                    MicrotaskQueue::CallEnqueueMicrotask)
836 
837 static int64_t atomic_pair_load(intptr_t address) {
838   return std::atomic_load(reinterpret_cast<std::atomic<int64_t>*>(address));
839 }
840 
atomic_pair_load_function()841 ExternalReference ExternalReference::atomic_pair_load_function() {
842   return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_load)));
843 }
844 
atomic_pair_store(intptr_t address,int value_low,int value_high)845 static void atomic_pair_store(intptr_t address, int value_low, int value_high) {
846   int64_t value =
847       static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
848   std::atomic_store(reinterpret_cast<std::atomic<int64_t>*>(address), value);
849 }
850 
atomic_pair_store_function()851 ExternalReference ExternalReference::atomic_pair_store_function() {
852   return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_store)));
853 }
854 
atomic_pair_add(intptr_t address,int value_low,int value_high)855 static int64_t atomic_pair_add(intptr_t address, int value_low,
856                                int value_high) {
857   int64_t value =
858       static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
859   return std::atomic_fetch_add(reinterpret_cast<std::atomic<int64_t>*>(address),
860                                value);
861 }
862 
atomic_pair_add_function()863 ExternalReference ExternalReference::atomic_pair_add_function() {
864   return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_add)));
865 }
866 
atomic_pair_sub(intptr_t address,int value_low,int value_high)867 static int64_t atomic_pair_sub(intptr_t address, int value_low,
868                                int value_high) {
869   int64_t value =
870       static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
871   return std::atomic_fetch_sub(reinterpret_cast<std::atomic<int64_t>*>(address),
872                                value);
873 }
874 
atomic_pair_sub_function()875 ExternalReference ExternalReference::atomic_pair_sub_function() {
876   return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_sub)));
877 }
878 
atomic_pair_and(intptr_t address,int value_low,int value_high)879 static int64_t atomic_pair_and(intptr_t address, int value_low,
880                                int value_high) {
881   int64_t value =
882       static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
883   return std::atomic_fetch_and(reinterpret_cast<std::atomic<int64_t>*>(address),
884                                value);
885 }
886 
atomic_pair_and_function()887 ExternalReference ExternalReference::atomic_pair_and_function() {
888   return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_and)));
889 }
890 
atomic_pair_or(intptr_t address,int value_low,int value_high)891 static int64_t atomic_pair_or(intptr_t address, int value_low, int value_high) {
892   int64_t value =
893       static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
894   return std::atomic_fetch_or(reinterpret_cast<std::atomic<int64_t>*>(address),
895                               value);
896 }
897 
atomic_pair_or_function()898 ExternalReference ExternalReference::atomic_pair_or_function() {
899   return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_or)));
900 }
901 
atomic_pair_xor(intptr_t address,int value_low,int value_high)902 static int64_t atomic_pair_xor(intptr_t address, int value_low,
903                                int value_high) {
904   int64_t value =
905       static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
906   return std::atomic_fetch_xor(reinterpret_cast<std::atomic<int64_t>*>(address),
907                                value);
908 }
909 
atomic_pair_xor_function()910 ExternalReference ExternalReference::atomic_pair_xor_function() {
911   return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_xor)));
912 }
913 
atomic_pair_exchange(intptr_t address,int value_low,int value_high)914 static int64_t atomic_pair_exchange(intptr_t address, int value_low,
915                                     int value_high) {
916   int64_t value =
917       static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
918   return std::atomic_exchange(reinterpret_cast<std::atomic<int64_t>*>(address),
919                               value);
920 }
921 
atomic_pair_exchange_function()922 ExternalReference ExternalReference::atomic_pair_exchange_function() {
923   return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_exchange)));
924 }
925 
atomic_pair_compare_exchange(intptr_t address,int old_value_low,int old_value_high,int new_value_low,int new_value_high)926 static uint64_t atomic_pair_compare_exchange(intptr_t address,
927                                              int old_value_low,
928                                              int old_value_high,
929                                              int new_value_low,
930                                              int new_value_high) {
931   uint64_t old_value = static_cast<uint64_t>(old_value_high) << 32 |
932                        (old_value_low & 0xFFFFFFFF);
933   uint64_t new_value = static_cast<uint64_t>(new_value_high) << 32 |
934                        (new_value_low & 0xFFFFFFFF);
935   std::atomic_compare_exchange_strong(
936       reinterpret_cast<std::atomic<uint64_t>*>(address), &old_value, new_value);
937   return old_value;
938 }
939 
FUNCTION_REFERENCE(atomic_pair_compare_exchange_function,atomic_pair_compare_exchange)940 FUNCTION_REFERENCE(atomic_pair_compare_exchange_function,
941                    atomic_pair_compare_exchange)
942 
943 static int EnterMicrotaskContextWrapper(HandleScopeImplementer* hsi,
944                                         Address raw_context) {
945   Context context = Context::cast(Object(raw_context));
946   hsi->EnterMicrotaskContext(context);
947   return 0;
948 }
949 
950 FUNCTION_REFERENCE(call_enter_context_function, EnterMicrotaskContextWrapper)
951 
952 FUNCTION_REFERENCE(
953     js_finalization_registry_remove_cell_from_unregister_token_map,
954     JSFinalizationRegistry::RemoveCellFromUnregisterTokenMap)
955 
956 #ifdef V8_HEAP_SANDBOX
957 FUNCTION_REFERENCE(external_pointer_table_grow_table_function,
958                    ExternalPointerTable::GrowTable)
959 #endif
960 
961 bool operator==(ExternalReference lhs, ExternalReference rhs) {
962   return lhs.address() == rhs.address();
963 }
964 
operator !=(ExternalReference lhs,ExternalReference rhs)965 bool operator!=(ExternalReference lhs, ExternalReference rhs) {
966   return !(lhs == rhs);
967 }
968 
hash_value(ExternalReference reference)969 size_t hash_value(ExternalReference reference) {
970   if (FLAG_predictable) {
971     // Avoid ASLR non-determinism in predictable mode. For this, just take the
972     // lowest 12 bit corresponding to a 4K page size.
973     return base::hash<Address>()(reference.address() & 0xfff);
974   }
975   return base::hash<Address>()(reference.address());
976 }
977 
operator <<(std::ostream & os,ExternalReference reference)978 std::ostream& operator<<(std::ostream& os, ExternalReference reference) {
979   os << reinterpret_cast<const void*>(reference.address());
980   const Runtime::Function* fn = Runtime::FunctionForEntry(reference.address());
981   if (fn) os << "<" << fn->name << ".entry>";
982   return os;
983 }
984 
abort_with_reason(int reason)985 void abort_with_reason(int reason) {
986   if (IsValidAbortReason(reason)) {
987     const char* message = GetAbortReason(static_cast<AbortReason>(reason));
988     base::OS::PrintError("abort: %s\n", message);
989   } else {
990     base::OS::PrintError("abort: <unknown reason: %d>\n", reason);
991   }
992   base::OS::Abort();
993   UNREACHABLE();
994 }
995 
996 #undef FUNCTION_REFERENCE
997 #undef FUNCTION_REFERENCE_WITH_ISOLATE
998 #undef FUNCTION_REFERENCE_WITH_TYPE
999 
1000 }  // namespace internal
1001 }  // namespace v8
1002