• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "include/v8-fast-api-calls.h"
8  #include "src/api/api-inl.h"
9  #include "src/base/ieee754.h"
10  #include "src/codegen/cpu-features.h"
11  #include "src/common/globals.h"
12  #include "src/date/date.h"
13  #include "src/debug/debug.h"
14  #include "src/deoptimizer/deoptimizer.h"
15  #include "src/execution/encoded-c-signature.h"
16  #include "src/execution/isolate-utils.h"
17  #include "src/execution/isolate.h"
18  #include "src/execution/microtask-queue.h"
19  #include "src/execution/simulator.h"
20  #include "src/heap/heap-inl.h"
21  #include "src/heap/heap.h"
22  #include "src/ic/stub-cache.h"
23  #include "src/interpreter/interpreter.h"
24  #include "src/logging/counters.h"
25  #include "src/logging/log.h"
26  #include "src/numbers/hash-seed-inl.h"
27  #include "src/numbers/math-random.h"
28  #include "src/objects/elements.h"
29  #include "src/objects/object-type.h"
30  #include "src/objects/objects-inl.h"
31  #include "src/objects/ordered-hash-table.h"
32  #include "src/regexp/experimental/experimental.h"
33  #include "src/regexp/regexp-interpreter.h"
34  #include "src/regexp/regexp-macro-assembler-arch.h"
35  #include "src/regexp/regexp-stack.h"
36  #include "src/strings/string-search.h"
37  
38  #if V8_ENABLE_WEBASSEMBLY
39  #include "src/wasm/wasm-external-refs.h"
40  #endif  // V8_ENABLE_WEBASSEMBLY
41  
42  #ifdef V8_INTL_SUPPORT
43  #include "src/base/platform/wrappers.h"
44  #include "src/base/strings.h"
45  #include "src/objects/intl-objects.h"
46  #endif  // V8_INTL_SUPPORT
47  
48  namespace v8 {
49  namespace internal {
50  
51  // -----------------------------------------------------------------------------
52  // Common double constants.
53  
54  constexpr double double_min_int_constant = kMinInt;
55  constexpr double double_one_half_constant = 0.5;
56  constexpr uint64_t double_the_hole_nan_constant = kHoleNanInt64;
57  constexpr double double_uint32_bias_constant =
58      static_cast<double>(kMaxUInt32) + 1;
59  
60  constexpr struct alignas(16) {
61    uint32_t a;
62    uint32_t b;
63    uint32_t c;
64    uint32_t d;
65  } float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
66  
67  constexpr struct alignas(16) {
68    uint32_t a;
69    uint32_t b;
70    uint32_t c;
71    uint32_t d;
72  } float_negate_constant = {0x80000000, 0x80000000, 0x80000000, 0x80000000};
73  
74  constexpr struct alignas(16) {
75    uint64_t a;
76    uint64_t b;
77  } double_absolute_constant = {uint64_t{0x7FFFFFFFFFFFFFFF},
78                                uint64_t{0x7FFFFFFFFFFFFFFF}};
79  
80  constexpr struct alignas(16) {
81    uint64_t a;
82    uint64_t b;
83  } double_negate_constant = {uint64_t{0x8000000000000000},
84                              uint64_t{0x8000000000000000}};
85  
86  constexpr struct alignas(16) {
87    uint64_t a;
88    uint64_t b;
89  } wasm_i8x16_swizzle_mask = {uint64_t{0x70707070'70707070},
90                               uint64_t{0x70707070'70707070}};
91  
92  constexpr struct alignas(16) {
93    uint64_t a;
94    uint64_t b;
95  } wasm_i8x16_popcnt_mask = {uint64_t{0x03020201'02010100},
96                              uint64_t{0x04030302'03020201}};
97  
98  constexpr struct alignas(16) {
99    uint64_t a;
100    uint64_t b;
101  } wasm_i8x16_splat_0x01 = {uint64_t{0x01010101'01010101},
102                             uint64_t{0x01010101'01010101}};
103  
104  constexpr struct alignas(16) {
105    uint64_t a;
106    uint64_t b;
107  } wasm_i8x16_splat_0x0f = {uint64_t{0x0F0F0F0F'0F0F0F0F},
108                             uint64_t{0x0F0F0F0F'0F0F0F0F}};
109  
110  constexpr struct alignas(16) {
111    uint64_t a;
112    uint64_t b;
113  } wasm_i8x16_splat_0x33 = {uint64_t{0x33333333'33333333},
114                             uint64_t{0x33333333'33333333}};
115  
116  constexpr struct alignas(16) {
117    uint64_t a;
118    uint64_t b;
119  } wasm_i8x16_splat_0x55 = {uint64_t{0x55555555'55555555},
120                             uint64_t{0x55555555'55555555}};
121  
122  constexpr struct alignas(16) {
123    uint64_t a;
124    uint64_t b;
125  } wasm_i16x8_splat_0x0001 = {uint64_t{0x00010001'00010001},
126                               uint64_t{0x00010001'00010001}};
127  
128  constexpr struct alignas(16) {
129    uint64_t a;
130    uint64_t b;
131  } wasm_f64x2_convert_low_i32x4_u_int_mask = {uint64_t{0x4330000043300000},
132                                               uint64_t{0x4330000043300000}};
133  
134  constexpr struct alignas(16) {
135    uint64_t a;
136    uint64_t b;
137  } wasm_double_2_power_52 = {uint64_t{0x4330000000000000},
138                              uint64_t{0x4330000000000000}};
139  
140  constexpr struct alignas(16) {
141    uint64_t a;
142    uint64_t b;
143  } wasm_int32_max_as_double = {uint64_t{0x41dfffffffc00000},
144                                uint64_t{0x41dfffffffc00000}};
145  
146  constexpr struct alignas(16) {
147    uint64_t a;
148    uint64_t b;
149  } wasm_uint32_max_as_double = {uint64_t{0x41efffffffe00000},
150                                 uint64_t{0x41efffffffe00000}};
151  
152  // This is 2147483648.0, which is 1 more than INT32_MAX.
153  constexpr struct alignas(16) {
154    uint32_t a;
155    uint32_t b;
156    uint32_t c;
157    uint32_t d;
158  } wasm_int32_overflow_as_float = {
159      uint32_t{0x4f00'0000},
160      uint32_t{0x4f00'0000},
161      uint32_t{0x4f00'0000},
162      uint32_t{0x4f00'0000},
163  };
164  
165  // Implementation of ExternalReference
166  
BuiltinCallTypeForResultSize(int result_size)167  static ExternalReference::Type BuiltinCallTypeForResultSize(int result_size) {
168    switch (result_size) {
169      case 1:
170        return ExternalReference::BUILTIN_CALL;
171      case 2:
172        return ExternalReference::BUILTIN_CALL_PAIR;
173    }
174    UNREACHABLE();
175  }
176  
177  // static
Create(ApiFunction * fun,Type type)178  ExternalReference ExternalReference::Create(ApiFunction* fun, Type type) {
179    return ExternalReference(Redirect(fun->address(), type));
180  }
181  
182  // static
Create(Isolate * isolate,ApiFunction * fun,Type type,Address * c_functions,const CFunctionInfo * const * c_signatures,unsigned num_functions)183  ExternalReference ExternalReference::Create(
184      Isolate* isolate, ApiFunction* fun, Type type, Address* c_functions,
185      const CFunctionInfo* const* c_signatures, unsigned num_functions) {
186  #ifdef V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
187    isolate->simulator_data()->RegisterFunctionsAndSignatures(
188        c_functions, c_signatures, num_functions);
189  #endif  //  V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
190    return ExternalReference(Redirect(fun->address(), type));
191  }
192  
193  // static
Create(Runtime::FunctionId id)194  ExternalReference ExternalReference::Create(Runtime::FunctionId id) {
195    return Create(Runtime::FunctionForId(id));
196  }
197  
198  // static
Create(const Runtime::Function * f)199  ExternalReference ExternalReference::Create(const Runtime::Function* f) {
200    return ExternalReference(
201        Redirect(f->entry, BuiltinCallTypeForResultSize(f->result_size)));
202  }
203  
204  // static
Create(Address address,Type type)205  ExternalReference ExternalReference::Create(Address address, Type type) {
206    return ExternalReference(Redirect(address, type));
207  }
208  
isolate_address(Isolate * isolate)209  ExternalReference ExternalReference::isolate_address(Isolate* isolate) {
210    return ExternalReference(isolate);
211  }
212  
builtins_table(Isolate * isolate)213  ExternalReference ExternalReference::builtins_table(Isolate* isolate) {
214    return ExternalReference(isolate->builtin_table());
215  }
216  
handle_scope_implementer_address(Isolate * isolate)217  ExternalReference ExternalReference::handle_scope_implementer_address(
218      Isolate* isolate) {
219    return ExternalReference(isolate->handle_scope_implementer_address());
220  }
221  
222  #ifdef V8_SANDBOXED_POINTERS
sandbox_base_address()223  ExternalReference ExternalReference::sandbox_base_address() {
224    return ExternalReference(GetProcessWideSandbox()->base_address());
225  }
226  
sandbox_end_address()227  ExternalReference ExternalReference::sandbox_end_address() {
228    return ExternalReference(GetProcessWideSandbox()->end_address());
229  }
230  
empty_backing_store_buffer()231  ExternalReference ExternalReference::empty_backing_store_buffer() {
232    return ExternalReference(GetProcessWideSandbox()
233                                 ->constants()
234                                 .empty_backing_store_buffer_address());
235  }
236  #endif  // V8_SANDBOXED_POINTERS
237  
238  #ifdef V8_SANDBOXED_EXTERNAL_POINTERS
external_pointer_table_address(Isolate * isolate)239  ExternalReference ExternalReference::external_pointer_table_address(
240      Isolate* isolate) {
241    return ExternalReference(isolate->external_pointer_table_address());
242  }
243  #endif  // V8_SANDBOXED_EXTERNAL_POINTERS
244  
interpreter_dispatch_table_address(Isolate * isolate)245  ExternalReference ExternalReference::interpreter_dispatch_table_address(
246      Isolate* isolate) {
247    return ExternalReference(isolate->interpreter()->dispatch_table_address());
248  }
249  
interpreter_dispatch_counters(Isolate * isolate)250  ExternalReference ExternalReference::interpreter_dispatch_counters(
251      Isolate* isolate) {
252    return ExternalReference(
253        isolate->interpreter()->bytecode_dispatch_counters_table());
254  }
255  
256  ExternalReference
address_of_interpreter_entry_trampoline_instruction_start(Isolate * isolate)257  ExternalReference::address_of_interpreter_entry_trampoline_instruction_start(
258      Isolate* isolate) {
259    return ExternalReference(
260        isolate->interpreter()
261            ->address_of_interpreter_entry_trampoline_instruction_start());
262  }
263  
bytecode_size_table_address()264  ExternalReference ExternalReference::bytecode_size_table_address() {
265    return ExternalReference(
266        interpreter::Bytecodes::bytecode_size_table_address());
267  }
268  
269  // static
Create(StatsCounter * counter)270  ExternalReference ExternalReference::Create(StatsCounter* counter) {
271    return ExternalReference(
272        reinterpret_cast<Address>(counter->GetInternalPointer()));
273  }
274  
275  // static
Create(IsolateAddressId id,Isolate * isolate)276  ExternalReference ExternalReference::Create(IsolateAddressId id,
277                                              Isolate* isolate) {
278    return ExternalReference(isolate->get_address_from_id(id));
279  }
280  
281  // static
Create(const SCTableReference & table_ref)282  ExternalReference ExternalReference::Create(const SCTableReference& table_ref) {
283    return ExternalReference(table_ref.address());
284  }
285  
286  namespace {
287  
288  // Helper function to verify that all types in a list of types are scalar.
289  // This includes primitive types (int, Address) and pointer types. We also
290  // allow void.
291  template <typename T>
AllScalar()292  constexpr bool AllScalar() {
293    return std::is_scalar<T>::value || std::is_void<T>::value;
294  }
295  
296  template <typename T1, typename T2, typename... Rest>
AllScalar()297  constexpr bool AllScalar() {
298    return AllScalar<T1>() && AllScalar<T2, Rest...>();
299  }
300  
301  // Checks a function pointer's type for compatibility with the
302  // ExternalReference calling mechanism. Specifically, all arguments
303  // as well as the result type must pass the AllScalar check above,
304  // because we expect each item to fit into one register or stack slot.
305  template <typename T>
306  struct IsValidExternalReferenceType;
307  
308  template <typename Result, typename... Args>
309  struct IsValidExternalReferenceType<Result (*)(Args...)> {
310    static const bool value = AllScalar<Result, Args...>();
311  };
312  
313  template <typename Result, typename Class, typename... Args>
314  struct IsValidExternalReferenceType<Result (Class::*)(Args...)> {
315    static const bool value = AllScalar<Result, Args...>();
316  };
317  
318  }  // namespace
319  
320  #define FUNCTION_REFERENCE(Name, Target)                                   \
321    ExternalReference ExternalReference::Name() {                            \
322      STATIC_ASSERT(IsValidExternalReferenceType<decltype(&Target)>::value); \
323      return ExternalReference(Redirect(FUNCTION_ADDR(Target)));             \
324    }
325  
326  #define FUNCTION_REFERENCE_WITH_TYPE(Name, Target, Type)                   \
327    ExternalReference ExternalReference::Name() {                            \
328      STATIC_ASSERT(IsValidExternalReferenceType<decltype(&Target)>::value); \
329      return ExternalReference(Redirect(FUNCTION_ADDR(Target), Type));       \
330    }
331  
FUNCTION_REFERENCE(write_barrier_marking_from_code_function,WriteBarrier::MarkingFromCode)332  FUNCTION_REFERENCE(write_barrier_marking_from_code_function,
333                     WriteBarrier::MarkingFromCode)
334  
335  FUNCTION_REFERENCE(insert_remembered_set_function,
336                     Heap::InsertIntoRememberedSetFromCode)
337  
338  FUNCTION_REFERENCE(delete_handle_scope_extensions,
339                     HandleScope::DeleteExtensions)
340  
341  FUNCTION_REFERENCE(ephemeron_key_write_barrier_function,
342                     Heap::EphemeronKeyWriteBarrierFromCode)
343  
344  FUNCTION_REFERENCE(get_date_field_function, JSDate::GetField)
345  
346  ExternalReference ExternalReference::date_cache_stamp(Isolate* isolate) {
347    return ExternalReference(isolate->date_cache()->stamp_address());
348  }
349  
350  // static
351  ExternalReference
runtime_function_table_address_for_unittests(Isolate * isolate)352  ExternalReference::runtime_function_table_address_for_unittests(
353      Isolate* isolate) {
354    return runtime_function_table_address(isolate);
355  }
356  
357  // static
Redirect(Address address,Type type)358  Address ExternalReference::Redirect(Address address, Type type) {
359  #ifdef USE_SIMULATOR
360    return SimulatorBase::RedirectExternalReference(address, type);
361  #else
362    return address;
363  #endif
364  }
365  
stress_deopt_count(Isolate * isolate)366  ExternalReference ExternalReference::stress_deopt_count(Isolate* isolate) {
367    return ExternalReference(isolate->stress_deopt_count_address());
368  }
369  
force_slow_path(Isolate * isolate)370  ExternalReference ExternalReference::force_slow_path(Isolate* isolate) {
371    return ExternalReference(isolate->force_slow_path_address());
372  }
373  
FUNCTION_REFERENCE(new_deoptimizer_function,Deoptimizer::New)374  FUNCTION_REFERENCE(new_deoptimizer_function, Deoptimizer::New)
375  
376  FUNCTION_REFERENCE(compute_output_frames_function,
377                     Deoptimizer::ComputeOutputFrames)
378  
379  IF_WASM(FUNCTION_REFERENCE, wasm_f32_trunc, wasm::f32_trunc_wrapper)
380  IF_WASM(FUNCTION_REFERENCE, wasm_f32_floor, wasm::f32_floor_wrapper)
381  IF_WASM(FUNCTION_REFERENCE, wasm_f32_ceil, wasm::f32_ceil_wrapper)
382  IF_WASM(FUNCTION_REFERENCE, wasm_f32_nearest_int, wasm::f32_nearest_int_wrapper)
383  IF_WASM(FUNCTION_REFERENCE, wasm_f64_trunc, wasm::f64_trunc_wrapper)
384  IF_WASM(FUNCTION_REFERENCE, wasm_f64_floor, wasm::f64_floor_wrapper)
385  IF_WASM(FUNCTION_REFERENCE, wasm_f64_ceil, wasm::f64_ceil_wrapper)
386  IF_WASM(FUNCTION_REFERENCE, wasm_f64_nearest_int, wasm::f64_nearest_int_wrapper)
387  IF_WASM(FUNCTION_REFERENCE, wasm_int64_to_float32,
388          wasm::int64_to_float32_wrapper)
389  IF_WASM(FUNCTION_REFERENCE, wasm_uint64_to_float32,
390          wasm::uint64_to_float32_wrapper)
391  IF_WASM(FUNCTION_REFERENCE, wasm_int64_to_float64,
392          wasm::int64_to_float64_wrapper)
393  IF_WASM(FUNCTION_REFERENCE, wasm_uint64_to_float64,
394          wasm::uint64_to_float64_wrapper)
395  IF_WASM(FUNCTION_REFERENCE, wasm_float32_to_int64,
396          wasm::float32_to_int64_wrapper)
397  IF_WASM(FUNCTION_REFERENCE, wasm_float32_to_uint64,
398          wasm::float32_to_uint64_wrapper)
399  IF_WASM(FUNCTION_REFERENCE, wasm_float64_to_int64,
400          wasm::float64_to_int64_wrapper)
401  IF_WASM(FUNCTION_REFERENCE, wasm_float64_to_uint64,
402          wasm::float64_to_uint64_wrapper)
403  IF_WASM(FUNCTION_REFERENCE, wasm_float32_to_int64_sat,
404          wasm::float32_to_int64_sat_wrapper)
405  IF_WASM(FUNCTION_REFERENCE, wasm_float32_to_uint64_sat,
406          wasm::float32_to_uint64_sat_wrapper)
407  IF_WASM(FUNCTION_REFERENCE, wasm_float64_to_int64_sat,
408          wasm::float64_to_int64_sat_wrapper)
409  IF_WASM(FUNCTION_REFERENCE, wasm_float64_to_uint64_sat,
410          wasm::float64_to_uint64_sat_wrapper)
411  IF_WASM(FUNCTION_REFERENCE, wasm_int64_div, wasm::int64_div_wrapper)
412  IF_WASM(FUNCTION_REFERENCE, wasm_int64_mod, wasm::int64_mod_wrapper)
413  IF_WASM(FUNCTION_REFERENCE, wasm_uint64_div, wasm::uint64_div_wrapper)
414  IF_WASM(FUNCTION_REFERENCE, wasm_uint64_mod, wasm::uint64_mod_wrapper)
415  IF_WASM(FUNCTION_REFERENCE, wasm_word32_ctz, wasm::word32_ctz_wrapper)
416  IF_WASM(FUNCTION_REFERENCE, wasm_word64_ctz, wasm::word64_ctz_wrapper)
417  IF_WASM(FUNCTION_REFERENCE, wasm_word32_popcnt, wasm::word32_popcnt_wrapper)
418  IF_WASM(FUNCTION_REFERENCE, wasm_word64_popcnt, wasm::word64_popcnt_wrapper)
419  IF_WASM(FUNCTION_REFERENCE, wasm_word32_rol, wasm::word32_rol_wrapper)
420  IF_WASM(FUNCTION_REFERENCE, wasm_word32_ror, wasm::word32_ror_wrapper)
421  IF_WASM(FUNCTION_REFERENCE, wasm_word64_rol, wasm::word64_rol_wrapper)
422  IF_WASM(FUNCTION_REFERENCE, wasm_word64_ror, wasm::word64_ror_wrapper)
423  IF_WASM(FUNCTION_REFERENCE, wasm_f64x2_ceil, wasm::f64x2_ceil_wrapper)
424  IF_WASM(FUNCTION_REFERENCE, wasm_f64x2_floor, wasm::f64x2_floor_wrapper)
425  IF_WASM(FUNCTION_REFERENCE, wasm_f64x2_trunc, wasm::f64x2_trunc_wrapper)
426  IF_WASM(FUNCTION_REFERENCE, wasm_f64x2_nearest_int,
427          wasm::f64x2_nearest_int_wrapper)
428  IF_WASM(FUNCTION_REFERENCE, wasm_f32x4_ceil, wasm::f32x4_ceil_wrapper)
429  IF_WASM(FUNCTION_REFERENCE, wasm_f32x4_floor, wasm::f32x4_floor_wrapper)
430  IF_WASM(FUNCTION_REFERENCE, wasm_f32x4_trunc, wasm::f32x4_trunc_wrapper)
431  IF_WASM(FUNCTION_REFERENCE, wasm_f32x4_nearest_int,
432          wasm::f32x4_nearest_int_wrapper)
433  IF_WASM(FUNCTION_REFERENCE, wasm_memory_init, wasm::memory_init_wrapper)
434  IF_WASM(FUNCTION_REFERENCE, wasm_memory_copy, wasm::memory_copy_wrapper)
435  IF_WASM(FUNCTION_REFERENCE, wasm_memory_fill, wasm::memory_fill_wrapper)
436  IF_WASM(FUNCTION_REFERENCE, wasm_float64_pow, wasm::float64_pow_wrapper)
437  IF_WASM(FUNCTION_REFERENCE, wasm_call_trap_callback_for_testing,
438          wasm::call_trap_callback_for_testing)
439  IF_WASM(FUNCTION_REFERENCE, wasm_array_copy, wasm::array_copy_wrapper)
440  
441  static void f64_acos_wrapper(Address data) {
442    double input = ReadUnalignedValue<double>(data);
443    WriteUnalignedValue(data, base::ieee754::acos(input));
444  }
445  
FUNCTION_REFERENCE(f64_acos_wrapper_function,f64_acos_wrapper)446  FUNCTION_REFERENCE(f64_acos_wrapper_function, f64_acos_wrapper)
447  
448  static void f64_asin_wrapper(Address data) {
449    double input = ReadUnalignedValue<double>(data);
450    WriteUnalignedValue<double>(data, base::ieee754::asin(input));
451  }
452  
FUNCTION_REFERENCE(f64_asin_wrapper_function,f64_asin_wrapper)453  FUNCTION_REFERENCE(f64_asin_wrapper_function, f64_asin_wrapper)
454  
455  
456  static void f64_mod_wrapper(Address data) {
457    double dividend = ReadUnalignedValue<double>(data);
458    double divisor = ReadUnalignedValue<double>(data + sizeof(dividend));
459    WriteUnalignedValue<double>(data, Modulo(dividend, divisor));
460  }
461  
FUNCTION_REFERENCE(f64_mod_wrapper_function,f64_mod_wrapper)462  FUNCTION_REFERENCE(f64_mod_wrapper_function, f64_mod_wrapper)
463  
464  ExternalReference ExternalReference::isolate_root(Isolate* isolate) {
465    return ExternalReference(isolate->isolate_root());
466  }
467  
allocation_sites_list_address(Isolate * isolate)468  ExternalReference ExternalReference::allocation_sites_list_address(
469      Isolate* isolate) {
470    return ExternalReference(isolate->heap()->allocation_sites_list_address());
471  }
472  
address_of_jslimit(Isolate * isolate)473  ExternalReference ExternalReference::address_of_jslimit(Isolate* isolate) {
474    Address address = isolate->stack_guard()->address_of_jslimit();
475    // For efficient generated code, this should be root-register-addressable.
476    DCHECK(isolate->root_register_addressable_region().contains(address));
477    return ExternalReference(address);
478  }
479  
address_of_real_jslimit(Isolate * isolate)480  ExternalReference ExternalReference::address_of_real_jslimit(Isolate* isolate) {
481    Address address = isolate->stack_guard()->address_of_real_jslimit();
482    // For efficient generated code, this should be root-register-addressable.
483    DCHECK(isolate->root_register_addressable_region().contains(address));
484    return ExternalReference(address);
485  }
486  
heap_is_marking_flag_address(Isolate * isolate)487  ExternalReference ExternalReference::heap_is_marking_flag_address(
488      Isolate* isolate) {
489    return ExternalReference(isolate->heap()->IsMarkingFlagAddress());
490  }
491  
new_space_allocation_top_address(Isolate * isolate)492  ExternalReference ExternalReference::new_space_allocation_top_address(
493      Isolate* isolate) {
494    return ExternalReference(isolate->heap()->NewSpaceAllocationTopAddress());
495  }
496  
new_space_allocation_limit_address(Isolate * isolate)497  ExternalReference ExternalReference::new_space_allocation_limit_address(
498      Isolate* isolate) {
499    return ExternalReference(isolate->heap()->NewSpaceAllocationLimitAddress());
500  }
501  
old_space_allocation_top_address(Isolate * isolate)502  ExternalReference ExternalReference::old_space_allocation_top_address(
503      Isolate* isolate) {
504    return ExternalReference(isolate->heap()->OldSpaceAllocationTopAddress());
505  }
506  
old_space_allocation_limit_address(Isolate * isolate)507  ExternalReference ExternalReference::old_space_allocation_limit_address(
508      Isolate* isolate) {
509    return ExternalReference(isolate->heap()->OldSpaceAllocationLimitAddress());
510  }
511  
handle_scope_level_address(Isolate * isolate)512  ExternalReference ExternalReference::handle_scope_level_address(
513      Isolate* isolate) {
514    return ExternalReference(HandleScope::current_level_address(isolate));
515  }
516  
handle_scope_next_address(Isolate * isolate)517  ExternalReference ExternalReference::handle_scope_next_address(
518      Isolate* isolate) {
519    return ExternalReference(HandleScope::current_next_address(isolate));
520  }
521  
handle_scope_limit_address(Isolate * isolate)522  ExternalReference ExternalReference::handle_scope_limit_address(
523      Isolate* isolate) {
524    return ExternalReference(HandleScope::current_limit_address(isolate));
525  }
526  
scheduled_exception_address(Isolate * isolate)527  ExternalReference ExternalReference::scheduled_exception_address(
528      Isolate* isolate) {
529    return ExternalReference(isolate->scheduled_exception_address());
530  }
531  
address_of_pending_message(Isolate * isolate)532  ExternalReference ExternalReference::address_of_pending_message(
533      Isolate* isolate) {
534    return ExternalReference(isolate->pending_message_address());
535  }
536  
address_of_pending_message(LocalIsolate * local_isolate)537  ExternalReference ExternalReference::address_of_pending_message(
538      LocalIsolate* local_isolate) {
539    return ExternalReference(local_isolate->pending_message_address());
540  }
541  
FUNCTION_REFERENCE(abort_with_reason,i::abort_with_reason)542  FUNCTION_REFERENCE(abort_with_reason, i::abort_with_reason)
543  
544  ExternalReference ExternalReference::address_of_min_int() {
545    return ExternalReference(reinterpret_cast<Address>(&double_min_int_constant));
546  }
547  
548  ExternalReference
address_of_mock_arraybuffer_allocator_flag()549  ExternalReference::address_of_mock_arraybuffer_allocator_flag() {
550    return ExternalReference(&FLAG_mock_arraybuffer_allocator);
551  }
552  
address_of_builtin_subclassing_flag()553  ExternalReference ExternalReference::address_of_builtin_subclassing_flag() {
554    return ExternalReference(&FLAG_builtin_subclassing);
555  }
556  
address_of_runtime_stats_flag()557  ExternalReference ExternalReference::address_of_runtime_stats_flag() {
558    return ExternalReference(&TracingFlags::runtime_stats);
559  }
560  
address_of_shared_string_table_flag()561  ExternalReference ExternalReference::address_of_shared_string_table_flag() {
562    return ExternalReference(&FLAG_shared_string_table);
563  }
564  
address_of_load_from_stack_count(const char * function_name)565  ExternalReference ExternalReference::address_of_load_from_stack_count(
566      const char* function_name) {
567    return ExternalReference(
568        Isolate::load_from_stack_count_address(function_name));
569  }
570  
address_of_store_to_stack_count(const char * function_name)571  ExternalReference ExternalReference::address_of_store_to_stack_count(
572      const char* function_name) {
573    return ExternalReference(
574        Isolate::store_to_stack_count_address(function_name));
575  }
576  
address_of_one_half()577  ExternalReference ExternalReference::address_of_one_half() {
578    return ExternalReference(
579        reinterpret_cast<Address>(&double_one_half_constant));
580  }
581  
address_of_the_hole_nan()582  ExternalReference ExternalReference::address_of_the_hole_nan() {
583    return ExternalReference(
584        reinterpret_cast<Address>(&double_the_hole_nan_constant));
585  }
586  
address_of_uint32_bias()587  ExternalReference ExternalReference::address_of_uint32_bias() {
588    return ExternalReference(
589        reinterpret_cast<Address>(&double_uint32_bias_constant));
590  }
591  
address_of_float_abs_constant()592  ExternalReference ExternalReference::address_of_float_abs_constant() {
593    return ExternalReference(reinterpret_cast<Address>(&float_absolute_constant));
594  }
595  
address_of_float_neg_constant()596  ExternalReference ExternalReference::address_of_float_neg_constant() {
597    return ExternalReference(reinterpret_cast<Address>(&float_negate_constant));
598  }
599  
address_of_double_abs_constant()600  ExternalReference ExternalReference::address_of_double_abs_constant() {
601    return ExternalReference(
602        reinterpret_cast<Address>(&double_absolute_constant));
603  }
604  
address_of_double_neg_constant()605  ExternalReference ExternalReference::address_of_double_neg_constant() {
606    return ExternalReference(reinterpret_cast<Address>(&double_negate_constant));
607  }
608  
address_of_wasm_i8x16_swizzle_mask()609  ExternalReference ExternalReference::address_of_wasm_i8x16_swizzle_mask() {
610    return ExternalReference(reinterpret_cast<Address>(&wasm_i8x16_swizzle_mask));
611  }
612  
address_of_wasm_i8x16_popcnt_mask()613  ExternalReference ExternalReference::address_of_wasm_i8x16_popcnt_mask() {
614    return ExternalReference(reinterpret_cast<Address>(&wasm_i8x16_popcnt_mask));
615  }
616  
address_of_wasm_i8x16_splat_0x01()617  ExternalReference ExternalReference::address_of_wasm_i8x16_splat_0x01() {
618    return ExternalReference(reinterpret_cast<Address>(&wasm_i8x16_splat_0x01));
619  }
620  
address_of_wasm_i8x16_splat_0x0f()621  ExternalReference ExternalReference::address_of_wasm_i8x16_splat_0x0f() {
622    return ExternalReference(reinterpret_cast<Address>(&wasm_i8x16_splat_0x0f));
623  }
624  
address_of_wasm_i8x16_splat_0x33()625  ExternalReference ExternalReference::address_of_wasm_i8x16_splat_0x33() {
626    return ExternalReference(reinterpret_cast<Address>(&wasm_i8x16_splat_0x33));
627  }
628  
address_of_wasm_i8x16_splat_0x55()629  ExternalReference ExternalReference::address_of_wasm_i8x16_splat_0x55() {
630    return ExternalReference(reinterpret_cast<Address>(&wasm_i8x16_splat_0x55));
631  }
632  
address_of_wasm_i16x8_splat_0x0001()633  ExternalReference ExternalReference::address_of_wasm_i16x8_splat_0x0001() {
634    return ExternalReference(reinterpret_cast<Address>(&wasm_i16x8_splat_0x0001));
635  }
636  
637  ExternalReference
address_of_wasm_f64x2_convert_low_i32x4_u_int_mask()638  ExternalReference::address_of_wasm_f64x2_convert_low_i32x4_u_int_mask() {
639    return ExternalReference(
640        reinterpret_cast<Address>(&wasm_f64x2_convert_low_i32x4_u_int_mask));
641  }
642  
supports_wasm_simd_128_address()643  ExternalReference ExternalReference::supports_wasm_simd_128_address() {
644    return ExternalReference(
645        reinterpret_cast<Address>(&CpuFeatures::supports_wasm_simd_128_));
646  }
647  
address_of_wasm_double_2_power_52()648  ExternalReference ExternalReference::address_of_wasm_double_2_power_52() {
649    return ExternalReference(reinterpret_cast<Address>(&wasm_double_2_power_52));
650  }
651  
address_of_wasm_int32_max_as_double()652  ExternalReference ExternalReference::address_of_wasm_int32_max_as_double() {
653    return ExternalReference(
654        reinterpret_cast<Address>(&wasm_int32_max_as_double));
655  }
656  
address_of_wasm_uint32_max_as_double()657  ExternalReference ExternalReference::address_of_wasm_uint32_max_as_double() {
658    return ExternalReference(
659        reinterpret_cast<Address>(&wasm_uint32_max_as_double));
660  }
661  
address_of_wasm_int32_overflow_as_float()662  ExternalReference ExternalReference::address_of_wasm_int32_overflow_as_float() {
663    return ExternalReference(
664        reinterpret_cast<Address>(&wasm_int32_overflow_as_float));
665  }
666  
supports_cetss_address()667  ExternalReference ExternalReference::supports_cetss_address() {
668    return ExternalReference(
669        reinterpret_cast<Address>(&CpuFeatures::supports_cetss_));
670  }
671  
672  ExternalReference
address_of_enable_experimental_regexp_engine()673  ExternalReference::address_of_enable_experimental_regexp_engine() {
674    return ExternalReference(&FLAG_enable_experimental_regexp_engine);
675  }
676  
677  namespace {
678  
BaselinePCForBytecodeOffset(Address raw_code_obj,int bytecode_offset,Address raw_bytecode_array)679  static uintptr_t BaselinePCForBytecodeOffset(Address raw_code_obj,
680                                               int bytecode_offset,
681                                               Address raw_bytecode_array) {
682    Code code_obj = Code::cast(Object(raw_code_obj));
683    BytecodeArray bytecode_array =
684        BytecodeArray::cast(Object(raw_bytecode_array));
685    return code_obj.GetBaselineStartPCForBytecodeOffset(bytecode_offset,
686                                                        bytecode_array);
687  }
688  
BaselinePCForNextExecutedBytecode(Address raw_code_obj,int bytecode_offset,Address raw_bytecode_array)689  static uintptr_t BaselinePCForNextExecutedBytecode(Address raw_code_obj,
690                                                     int bytecode_offset,
691                                                     Address raw_bytecode_array) {
692    Code code_obj = Code::cast(Object(raw_code_obj));
693    BytecodeArray bytecode_array =
694        BytecodeArray::cast(Object(raw_bytecode_array));
695    return code_obj.GetBaselinePCForNextExecutedBytecode(bytecode_offset,
696                                                         bytecode_array);
697  }
698  
699  }  // namespace
700  
FUNCTION_REFERENCE(baseline_pc_for_bytecode_offset,BaselinePCForBytecodeOffset)701  FUNCTION_REFERENCE(baseline_pc_for_bytecode_offset, BaselinePCForBytecodeOffset)
702  FUNCTION_REFERENCE(baseline_pc_for_next_executed_bytecode,
703                     BaselinePCForNextExecutedBytecode)
704  
705  ExternalReference ExternalReference::thread_in_wasm_flag_address_address(
706      Isolate* isolate) {
707    return ExternalReference(isolate->thread_in_wasm_flag_address_address());
708  }
709  
is_profiling_address(Isolate * isolate)710  ExternalReference ExternalReference::is_profiling_address(Isolate* isolate) {
711    return ExternalReference(isolate->is_profiling_address());
712  }
713  
invoke_function_callback()714  ExternalReference ExternalReference::invoke_function_callback() {
715    Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
716    ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
717    ApiFunction thunk_fun(thunk_address);
718    return ExternalReference::Create(&thunk_fun, thunk_type);
719  }
720  
invoke_accessor_getter_callback()721  ExternalReference ExternalReference::invoke_accessor_getter_callback() {
722    Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
723    ExternalReference::Type thunk_type = ExternalReference::PROFILING_GETTER_CALL;
724    ApiFunction thunk_fun(thunk_address);
725    return ExternalReference::Create(&thunk_fun, thunk_type);
726  }
727  
728  #if V8_TARGET_ARCH_X64
729  #define re_stack_check_func RegExpMacroAssemblerX64::CheckStackGuardState
730  #elif V8_TARGET_ARCH_IA32
731  #define re_stack_check_func RegExpMacroAssemblerIA32::CheckStackGuardState
732  #elif V8_TARGET_ARCH_ARM64
733  #define re_stack_check_func RegExpMacroAssemblerARM64::CheckStackGuardState
734  #elif V8_TARGET_ARCH_ARM
735  #define re_stack_check_func RegExpMacroAssemblerARM::CheckStackGuardState
736  #elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
737  #define re_stack_check_func RegExpMacroAssemblerPPC::CheckStackGuardState
738  #elif V8_TARGET_ARCH_MIPS
739  #define re_stack_check_func RegExpMacroAssemblerMIPS::CheckStackGuardState
740  #elif V8_TARGET_ARCH_MIPS64
741  #define re_stack_check_func RegExpMacroAssemblerMIPS::CheckStackGuardState
742  #elif V8_TARGET_ARCH_LOONG64
743  #define re_stack_check_func RegExpMacroAssemblerLOONG64::CheckStackGuardState
744  #elif V8_TARGET_ARCH_S390
745  #define re_stack_check_func RegExpMacroAssemblerS390::CheckStackGuardState
746  #elif V8_TARGET_ARCH_RISCV64
747  #define re_stack_check_func RegExpMacroAssemblerRISCV::CheckStackGuardState
748  #else
749  UNREACHABLE();
750  #endif
751  
FUNCTION_REFERENCE(re_check_stack_guard_state,re_stack_check_func)752  FUNCTION_REFERENCE(re_check_stack_guard_state, re_stack_check_func)
753  #undef re_stack_check_func
754  
755  FUNCTION_REFERENCE(re_grow_stack, NativeRegExpMacroAssembler::GrowStack)
756  
757  FUNCTION_REFERENCE(re_match_for_call_from_js,
758                     IrregexpInterpreter::MatchForCallFromJs)
759  
760  FUNCTION_REFERENCE(re_experimental_match_for_call_from_js,
761                     ExperimentalRegExp::MatchForCallFromJs)
762  
763  FUNCTION_REFERENCE(re_case_insensitive_compare_unicode,
764                     NativeRegExpMacroAssembler::CaseInsensitiveCompareUnicode)
765  
766  FUNCTION_REFERENCE(re_case_insensitive_compare_non_unicode,
767                     NativeRegExpMacroAssembler::CaseInsensitiveCompareNonUnicode)
768  
769  FUNCTION_REFERENCE(re_is_character_in_range_array,
770                     RegExpMacroAssembler::IsCharacterInRangeArray)
771  
772  ExternalReference ExternalReference::re_word_character_map() {
773    return ExternalReference(
774        NativeRegExpMacroAssembler::word_character_map_address());
775  }
776  
address_of_static_offsets_vector(Isolate * isolate)777  ExternalReference ExternalReference::address_of_static_offsets_vector(
778      Isolate* isolate) {
779    return ExternalReference(
780        reinterpret_cast<Address>(isolate->jsregexp_static_offsets_vector()));
781  }
782  
address_of_regexp_stack_limit_address(Isolate * isolate)783  ExternalReference ExternalReference::address_of_regexp_stack_limit_address(
784      Isolate* isolate) {
785    return ExternalReference(isolate->regexp_stack()->limit_address_address());
786  }
787  
address_of_regexp_stack_memory_top_address(Isolate * isolate)788  ExternalReference ExternalReference::address_of_regexp_stack_memory_top_address(
789      Isolate* isolate) {
790    return ExternalReference(
791        isolate->regexp_stack()->memory_top_address_address());
792  }
793  
address_of_regexp_stack_stack_pointer(Isolate * isolate)794  ExternalReference ExternalReference::address_of_regexp_stack_stack_pointer(
795      Isolate* isolate) {
796    return ExternalReference(isolate->regexp_stack()->stack_pointer_address());
797  }
798  
javascript_execution_assert(Isolate * isolate)799  ExternalReference ExternalReference::javascript_execution_assert(
800      Isolate* isolate) {
801    return ExternalReference(isolate->javascript_execution_assert_address());
802  }
803  
FUNCTION_REFERENCE_WITH_TYPE(ieee754_acos_function,base::ieee754::acos,BUILTIN_FP_CALL)804  FUNCTION_REFERENCE_WITH_TYPE(ieee754_acos_function, base::ieee754::acos,
805                               BUILTIN_FP_CALL)
806  FUNCTION_REFERENCE_WITH_TYPE(ieee754_acosh_function, base::ieee754::acosh,
807                               BUILTIN_FP_CALL)
808  FUNCTION_REFERENCE_WITH_TYPE(ieee754_asin_function, base::ieee754::asin,
809                               BUILTIN_FP_CALL)
810  FUNCTION_REFERENCE_WITH_TYPE(ieee754_asinh_function, base::ieee754::asinh,
811                               BUILTIN_FP_CALL)
812  FUNCTION_REFERENCE_WITH_TYPE(ieee754_atan_function, base::ieee754::atan,
813                               BUILTIN_FP_CALL)
814  FUNCTION_REFERENCE_WITH_TYPE(ieee754_atanh_function, base::ieee754::atanh,
815                               BUILTIN_FP_CALL)
816  FUNCTION_REFERENCE_WITH_TYPE(ieee754_atan2_function, base::ieee754::atan2,
817                               BUILTIN_FP_FP_CALL)
818  FUNCTION_REFERENCE_WITH_TYPE(ieee754_cbrt_function, base::ieee754::cbrt,
819                               BUILTIN_FP_CALL)
820  FUNCTION_REFERENCE_WITH_TYPE(ieee754_cos_function, base::ieee754::cos,
821                               BUILTIN_FP_CALL)
822  FUNCTION_REFERENCE_WITH_TYPE(ieee754_cosh_function, base::ieee754::cosh,
823                               BUILTIN_FP_CALL)
824  FUNCTION_REFERENCE_WITH_TYPE(ieee754_exp_function, base::ieee754::exp,
825                               BUILTIN_FP_CALL)
826  FUNCTION_REFERENCE_WITH_TYPE(ieee754_expm1_function, base::ieee754::expm1,
827                               BUILTIN_FP_CALL)
828  FUNCTION_REFERENCE_WITH_TYPE(ieee754_log_function, base::ieee754::log,
829                               BUILTIN_FP_CALL)
830  FUNCTION_REFERENCE_WITH_TYPE(ieee754_log1p_function, base::ieee754::log1p,
831                               BUILTIN_FP_CALL)
832  FUNCTION_REFERENCE_WITH_TYPE(ieee754_log10_function, base::ieee754::log10,
833                               BUILTIN_FP_CALL)
834  FUNCTION_REFERENCE_WITH_TYPE(ieee754_log2_function, base::ieee754::log2,
835                               BUILTIN_FP_CALL)
836  FUNCTION_REFERENCE_WITH_TYPE(ieee754_sin_function, base::ieee754::sin,
837                               BUILTIN_FP_CALL)
838  FUNCTION_REFERENCE_WITH_TYPE(ieee754_sinh_function, base::ieee754::sinh,
839                               BUILTIN_FP_CALL)
840  FUNCTION_REFERENCE_WITH_TYPE(ieee754_tan_function, base::ieee754::tan,
841                               BUILTIN_FP_CALL)
842  FUNCTION_REFERENCE_WITH_TYPE(ieee754_tanh_function, base::ieee754::tanh,
843                               BUILTIN_FP_CALL)
844  FUNCTION_REFERENCE_WITH_TYPE(ieee754_pow_function, base::ieee754::pow,
845                               BUILTIN_FP_FP_CALL)
846  
847  void* libc_memchr(void* string, int character, size_t search_length) {
848    return memchr(string, character, search_length);
849  }
850  
FUNCTION_REFERENCE(libc_memchr_function,libc_memchr)851  FUNCTION_REFERENCE(libc_memchr_function, libc_memchr)
852  
853  void* libc_memcpy(void* dest, const void* src, size_t n) {
854    return memcpy(dest, src, n);
855  }
856  
FUNCTION_REFERENCE(libc_memcpy_function,libc_memcpy)857  FUNCTION_REFERENCE(libc_memcpy_function, libc_memcpy)
858  
859  void* libc_memmove(void* dest, const void* src, size_t n) {
860    return memmove(dest, src, n);
861  }
862  
FUNCTION_REFERENCE(libc_memmove_function,libc_memmove)863  FUNCTION_REFERENCE(libc_memmove_function, libc_memmove)
864  
865  void* libc_memset(void* dest, int value, size_t n) {
866    DCHECK_EQ(static_cast<byte>(value), value);
867    return memset(dest, value, n);
868  }
869  
FUNCTION_REFERENCE(libc_memset_function,libc_memset)870  FUNCTION_REFERENCE(libc_memset_function, libc_memset)
871  
872  void relaxed_memcpy(volatile base::Atomic8* dest,
873                      volatile const base::Atomic8* src, size_t n) {
874    base::Relaxed_Memcpy(dest, src, n);
875  }
876  
FUNCTION_REFERENCE(relaxed_memcpy_function,relaxed_memcpy)877  FUNCTION_REFERENCE(relaxed_memcpy_function, relaxed_memcpy)
878  
879  void relaxed_memmove(volatile base::Atomic8* dest,
880                       volatile const base::Atomic8* src, size_t n) {
881    base::Relaxed_Memmove(dest, src, n);
882  }
883  
FUNCTION_REFERENCE(relaxed_memmove_function,relaxed_memmove)884  FUNCTION_REFERENCE(relaxed_memmove_function, relaxed_memmove)
885  
886  ExternalReference ExternalReference::printf_function() {
887    return ExternalReference(Redirect(FUNCTION_ADDR(std::printf)));
888  }
889  
FUNCTION_REFERENCE(refill_math_random,MathRandom::RefillCache)890  FUNCTION_REFERENCE(refill_math_random, MathRandom::RefillCache)
891  
892  template <typename SubjectChar, typename PatternChar>
893  ExternalReference ExternalReference::search_string_raw() {
894    auto f = SearchStringRaw<SubjectChar, PatternChar>;
895    return ExternalReference(Redirect(FUNCTION_ADDR(f)));
896  }
897  
FUNCTION_REFERENCE(jsarray_array_join_concat_to_sequential_string,JSArray::ArrayJoinConcatToSequentialString)898  FUNCTION_REFERENCE(jsarray_array_join_concat_to_sequential_string,
899                     JSArray::ArrayJoinConcatToSequentialString)
900  
901  FUNCTION_REFERENCE(gsab_byte_length, JSArrayBuffer::GsabByteLength)
902  
903  ExternalReference ExternalReference::search_string_raw_one_one() {
904    return search_string_raw<const uint8_t, const uint8_t>();
905  }
906  
search_string_raw_one_two()907  ExternalReference ExternalReference::search_string_raw_one_two() {
908    return search_string_raw<const uint8_t, const base::uc16>();
909  }
910  
search_string_raw_two_one()911  ExternalReference ExternalReference::search_string_raw_two_one() {
912    return search_string_raw<const base::uc16, const uint8_t>();
913  }
914  
search_string_raw_two_two()915  ExternalReference ExternalReference::search_string_raw_two_two() {
916    return search_string_raw<const base::uc16, const base::uc16>();
917  }
918  
919  namespace {
920  
StringWriteToFlatOneByte(Address source,uint8_t * sink,int32_t start,int32_t length)921  void StringWriteToFlatOneByte(Address source, uint8_t* sink, int32_t start,
922                                int32_t length) {
923    return String::WriteToFlat<uint8_t>(String::cast(Object(source)), sink, start,
924                                        length);
925  }
926  
StringWriteToFlatTwoByte(Address source,uint16_t * sink,int32_t start,int32_t length)927  void StringWriteToFlatTwoByte(Address source, uint16_t* sink, int32_t start,
928                                int32_t length) {
929    return String::WriteToFlat<uint16_t>(String::cast(Object(source)), sink,
930                                         start, length);
931  }
932  
ExternalOneByteStringGetChars(Address string)933  const uint8_t* ExternalOneByteStringGetChars(Address string) {
934    PtrComprCageBase cage_base = GetPtrComprCageBaseFromOnHeapAddress(string);
935    // The following CHECK is a workaround to prevent a CFI bug where
936    // ExternalOneByteStringGetChars() and ExternalTwoByteStringGetChars() are
937    // merged by the linker, resulting in one of the input type's vtable address
938    // failing the address range check.
939    // TODO(chromium:1160961): Consider removing the CHECK when CFI is fixed.
940    CHECK(Object(string).IsExternalOneByteString(cage_base));
941    return ExternalOneByteString::cast(Object(string)).GetChars(cage_base);
942  }
ExternalTwoByteStringGetChars(Address string)943  const uint16_t* ExternalTwoByteStringGetChars(Address string) {
944    PtrComprCageBase cage_base = GetPtrComprCageBaseFromOnHeapAddress(string);
945    // The following CHECK is a workaround to prevent a CFI bug where
946    // ExternalOneByteStringGetChars() and ExternalTwoByteStringGetChars() are
947    // merged by the linker, resulting in one of the input type's vtable address
948    // failing the address range check.
949    // TODO(chromium:1160961): Consider removing the CHECK when CFI is fixed.
950    CHECK(Object(string).IsExternalTwoByteString(cage_base));
951    return ExternalTwoByteString::cast(Object(string)).GetChars(cage_base);
952  }
953  
954  }  // namespace
955  
FUNCTION_REFERENCE(string_write_to_flat_one_byte,StringWriteToFlatOneByte)956  FUNCTION_REFERENCE(string_write_to_flat_one_byte, StringWriteToFlatOneByte)
957  FUNCTION_REFERENCE(string_write_to_flat_two_byte, StringWriteToFlatTwoByte)
958  
959  FUNCTION_REFERENCE(external_one_byte_string_get_chars,
960                     ExternalOneByteStringGetChars)
961  FUNCTION_REFERENCE(external_two_byte_string_get_chars,
962                     ExternalTwoByteStringGetChars)
963  
964  FUNCTION_REFERENCE(orderedhashmap_gethash_raw, OrderedHashMap::GetHash)
965  
966  Address GetOrCreateHash(Isolate* isolate, Address raw_key) {
967    DisallowGarbageCollection no_gc;
968    return Object(raw_key).GetOrCreateHash(isolate).ptr();
969  }
970  
FUNCTION_REFERENCE(get_or_create_hash_raw,GetOrCreateHash)971  FUNCTION_REFERENCE(get_or_create_hash_raw, GetOrCreateHash)
972  
973  static Address JSReceiverCreateIdentityHash(Isolate* isolate, Address raw_key) {
974    JSReceiver key = JSReceiver::cast(Object(raw_key));
975    return JSReceiver::CreateIdentityHash(isolate, key).ptr();
976  }
977  
FUNCTION_REFERENCE(jsreceiver_create_identity_hash,JSReceiverCreateIdentityHash)978  FUNCTION_REFERENCE(jsreceiver_create_identity_hash,
979                     JSReceiverCreateIdentityHash)
980  
981  static uint32_t ComputeSeededIntegerHash(Isolate* isolate, int32_t key) {
982    DisallowGarbageCollection no_gc;
983    return ComputeSeededHash(static_cast<uint32_t>(key), HashSeed(isolate));
984  }
985  
FUNCTION_REFERENCE(compute_integer_hash,ComputeSeededIntegerHash)986  FUNCTION_REFERENCE(compute_integer_hash, ComputeSeededIntegerHash)
987  FUNCTION_REFERENCE(copy_fast_number_jsarray_elements_to_typed_array,
988                     CopyFastNumberJSArrayElementsToTypedArray)
989  FUNCTION_REFERENCE(copy_typed_array_elements_to_typed_array,
990                     CopyTypedArrayElementsToTypedArray)
991  FUNCTION_REFERENCE(copy_typed_array_elements_slice, CopyTypedArrayElementsSlice)
992  FUNCTION_REFERENCE(try_string_to_index_or_lookup_existing,
993                     StringTable::TryStringToIndexOrLookupExisting)
994  FUNCTION_REFERENCE(string_to_array_index_function, String::ToArrayIndex)
995  
996  static Address LexicographicCompareWrapper(Isolate* isolate, Address smi_x,
997                                             Address smi_y) {
998    Smi x(smi_x);
999    Smi y(smi_y);
1000    return Smi::LexicographicCompare(isolate, x, y);
1001  }
1002  
FUNCTION_REFERENCE(smi_lexicographic_compare_function,LexicographicCompareWrapper)1003  FUNCTION_REFERENCE(smi_lexicographic_compare_function,
1004                     LexicographicCompareWrapper)
1005  
1006  FUNCTION_REFERENCE(mutable_big_int_absolute_add_and_canonicalize_function,
1007                     MutableBigInt_AbsoluteAddAndCanonicalize)
1008  
1009  FUNCTION_REFERENCE(mutable_big_int_absolute_compare_function,
1010                     MutableBigInt_AbsoluteCompare)
1011  
1012  FUNCTION_REFERENCE(mutable_big_int_absolute_sub_and_canonicalize_function,
1013                     MutableBigInt_AbsoluteSubAndCanonicalize)
1014  
1015  FUNCTION_REFERENCE(check_object_type, CheckObjectType)
1016  
1017  #ifdef V8_INTL_SUPPORT
1018  
1019  static Address ConvertOneByteToLower(Address raw_src, Address raw_dst) {
1020    String src = String::cast(Object(raw_src));
1021    String dst = String::cast(Object(raw_dst));
1022    return Intl::ConvertOneByteToLower(src, dst).ptr();
1023  }
FUNCTION_REFERENCE(intl_convert_one_byte_to_lower,ConvertOneByteToLower)1024  FUNCTION_REFERENCE(intl_convert_one_byte_to_lower, ConvertOneByteToLower)
1025  
1026  ExternalReference ExternalReference::intl_to_latin1_lower_table() {
1027    uint8_t* ptr = const_cast<uint8_t*>(Intl::ToLatin1LowerTable());
1028    return ExternalReference(reinterpret_cast<Address>(ptr));
1029  }
1030  
intl_ascii_collation_weights_l1()1031  ExternalReference ExternalReference::intl_ascii_collation_weights_l1() {
1032    uint8_t* ptr = const_cast<uint8_t*>(Intl::AsciiCollationWeightsL1());
1033    return ExternalReference(reinterpret_cast<Address>(ptr));
1034  }
1035  
intl_ascii_collation_weights_l3()1036  ExternalReference ExternalReference::intl_ascii_collation_weights_l3() {
1037    uint8_t* ptr = const_cast<uint8_t*>(Intl::AsciiCollationWeightsL3());
1038    return ExternalReference(reinterpret_cast<Address>(ptr));
1039  }
1040  
1041  #endif  // V8_INTL_SUPPORT
1042  
1043  // Explicit instantiations for all combinations of 1- and 2-byte strings.
1044  template ExternalReference
1045  ExternalReference::search_string_raw<const uint8_t, const uint8_t>();
1046  template ExternalReference
1047  ExternalReference::search_string_raw<const uint8_t, const base::uc16>();
1048  template ExternalReference
1049  ExternalReference::search_string_raw<const base::uc16, const uint8_t>();
1050  template ExternalReference
1051  ExternalReference::search_string_raw<const base::uc16, const base::uc16>();
1052  
FromRawAddress(Address address)1053  ExternalReference ExternalReference::FromRawAddress(Address address) {
1054    return ExternalReference(address);
1055  }
1056  
cpu_features()1057  ExternalReference ExternalReference::cpu_features() {
1058    DCHECK(CpuFeatures::initialized_);
1059    return ExternalReference(&CpuFeatures::supported_);
1060  }
1061  
promise_hook_flags_address(Isolate * isolate)1062  ExternalReference ExternalReference::promise_hook_flags_address(
1063      Isolate* isolate) {
1064    return ExternalReference(isolate->promise_hook_flags_address());
1065  }
1066  
promise_hook_address(Isolate * isolate)1067  ExternalReference ExternalReference::promise_hook_address(Isolate* isolate) {
1068    return ExternalReference(isolate->promise_hook_address());
1069  }
1070  
async_event_delegate_address(Isolate * isolate)1071  ExternalReference ExternalReference::async_event_delegate_address(
1072      Isolate* isolate) {
1073    return ExternalReference(isolate->async_event_delegate_address());
1074  }
1075  
debug_execution_mode_address(Isolate * isolate)1076  ExternalReference ExternalReference::debug_execution_mode_address(
1077      Isolate* isolate) {
1078    return ExternalReference(isolate->debug_execution_mode_address());
1079  }
1080  
debug_is_active_address(Isolate * isolate)1081  ExternalReference ExternalReference::debug_is_active_address(Isolate* isolate) {
1082    return ExternalReference(isolate->debug()->is_active_address());
1083  }
1084  
debug_hook_on_function_call_address(Isolate * isolate)1085  ExternalReference ExternalReference::debug_hook_on_function_call_address(
1086      Isolate* isolate) {
1087    return ExternalReference(isolate->debug()->hook_on_function_call_address());
1088  }
1089  
runtime_function_table_address(Isolate * isolate)1090  ExternalReference ExternalReference::runtime_function_table_address(
1091      Isolate* isolate) {
1092    return ExternalReference(
1093        const_cast<Runtime::Function*>(Runtime::RuntimeFunctionTable(isolate)));
1094  }
1095  
InvalidatePrototypeChainsWrapper(Address raw_map)1096  static Address InvalidatePrototypeChainsWrapper(Address raw_map) {
1097    Map map = Map::cast(Object(raw_map));
1098    return JSObject::InvalidatePrototypeChains(map).ptr();
1099  }
1100  
FUNCTION_REFERENCE(invalidate_prototype_chains_function,InvalidatePrototypeChainsWrapper)1101  FUNCTION_REFERENCE(invalidate_prototype_chains_function,
1102                     InvalidatePrototypeChainsWrapper)
1103  
1104  double modulo_double_double(double x, double y) { return Modulo(x, y); }
1105  
FUNCTION_REFERENCE_WITH_TYPE(mod_two_doubles_operation,modulo_double_double,BUILTIN_FP_FP_CALL)1106  FUNCTION_REFERENCE_WITH_TYPE(mod_two_doubles_operation, modulo_double_double,
1107                               BUILTIN_FP_FP_CALL)
1108  
1109  ExternalReference ExternalReference::debug_suspended_generator_address(
1110      Isolate* isolate) {
1111    return ExternalReference(isolate->debug()->suspended_generator_address());
1112  }
1113  
fast_c_call_caller_fp_address(Isolate * isolate)1114  ExternalReference ExternalReference::fast_c_call_caller_fp_address(
1115      Isolate* isolate) {
1116    return ExternalReference(
1117        isolate->isolate_data()->fast_c_call_caller_fp_address());
1118  }
1119  
fast_c_call_caller_pc_address(Isolate * isolate)1120  ExternalReference ExternalReference::fast_c_call_caller_pc_address(
1121      Isolate* isolate) {
1122    return ExternalReference(
1123        isolate->isolate_data()->fast_c_call_caller_pc_address());
1124  }
1125  
fast_api_call_target_address(Isolate * isolate)1126  ExternalReference ExternalReference::fast_api_call_target_address(
1127      Isolate* isolate) {
1128    return ExternalReference(
1129        isolate->isolate_data()->fast_api_call_target_address());
1130  }
1131  
stack_is_iterable_address(Isolate * isolate)1132  ExternalReference ExternalReference::stack_is_iterable_address(
1133      Isolate* isolate) {
1134    return ExternalReference(
1135        isolate->isolate_data()->stack_is_iterable_address());
1136  }
1137  
FUNCTION_REFERENCE(call_enqueue_microtask_function,MicrotaskQueue::CallEnqueueMicrotask)1138  FUNCTION_REFERENCE(call_enqueue_microtask_function,
1139                     MicrotaskQueue::CallEnqueueMicrotask)
1140  
1141  static int64_t atomic_pair_load(intptr_t address) {
1142    return std::atomic_load(reinterpret_cast<std::atomic<int64_t>*>(address));
1143  }
1144  
atomic_pair_load_function()1145  ExternalReference ExternalReference::atomic_pair_load_function() {
1146    return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_load)));
1147  }
1148  
atomic_pair_store(intptr_t address,int value_low,int value_high)1149  static void atomic_pair_store(intptr_t address, int value_low, int value_high) {
1150    int64_t value =
1151        static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
1152    std::atomic_store(reinterpret_cast<std::atomic<int64_t>*>(address), value);
1153  }
1154  
atomic_pair_store_function()1155  ExternalReference ExternalReference::atomic_pair_store_function() {
1156    return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_store)));
1157  }
1158  
atomic_pair_add(intptr_t address,int value_low,int value_high)1159  static int64_t atomic_pair_add(intptr_t address, int value_low,
1160                                 int value_high) {
1161    int64_t value =
1162        static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
1163    return std::atomic_fetch_add(reinterpret_cast<std::atomic<int64_t>*>(address),
1164                                 value);
1165  }
1166  
atomic_pair_add_function()1167  ExternalReference ExternalReference::atomic_pair_add_function() {
1168    return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_add)));
1169  }
1170  
atomic_pair_sub(intptr_t address,int value_low,int value_high)1171  static int64_t atomic_pair_sub(intptr_t address, int value_low,
1172                                 int value_high) {
1173    int64_t value =
1174        static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
1175    return std::atomic_fetch_sub(reinterpret_cast<std::atomic<int64_t>*>(address),
1176                                 value);
1177  }
1178  
atomic_pair_sub_function()1179  ExternalReference ExternalReference::atomic_pair_sub_function() {
1180    return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_sub)));
1181  }
1182  
atomic_pair_and(intptr_t address,int value_low,int value_high)1183  static int64_t atomic_pair_and(intptr_t address, int value_low,
1184                                 int value_high) {
1185    int64_t value =
1186        static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
1187    return std::atomic_fetch_and(reinterpret_cast<std::atomic<int64_t>*>(address),
1188                                 value);
1189  }
1190  
atomic_pair_and_function()1191  ExternalReference ExternalReference::atomic_pair_and_function() {
1192    return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_and)));
1193  }
1194  
atomic_pair_or(intptr_t address,int value_low,int value_high)1195  static int64_t atomic_pair_or(intptr_t address, int value_low, int value_high) {
1196    int64_t value =
1197        static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
1198    return std::atomic_fetch_or(reinterpret_cast<std::atomic<int64_t>*>(address),
1199                                value);
1200  }
1201  
atomic_pair_or_function()1202  ExternalReference ExternalReference::atomic_pair_or_function() {
1203    return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_or)));
1204  }
1205  
atomic_pair_xor(intptr_t address,int value_low,int value_high)1206  static int64_t atomic_pair_xor(intptr_t address, int value_low,
1207                                 int value_high) {
1208    int64_t value =
1209        static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
1210    return std::atomic_fetch_xor(reinterpret_cast<std::atomic<int64_t>*>(address),
1211                                 value);
1212  }
1213  
atomic_pair_xor_function()1214  ExternalReference ExternalReference::atomic_pair_xor_function() {
1215    return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_xor)));
1216  }
1217  
atomic_pair_exchange(intptr_t address,int value_low,int value_high)1218  static int64_t atomic_pair_exchange(intptr_t address, int value_low,
1219                                      int value_high) {
1220    int64_t value =
1221        static_cast<int64_t>(value_high) << 32 | (value_low & 0xFFFFFFFF);
1222    return std::atomic_exchange(reinterpret_cast<std::atomic<int64_t>*>(address),
1223                                value);
1224  }
1225  
atomic_pair_exchange_function()1226  ExternalReference ExternalReference::atomic_pair_exchange_function() {
1227    return ExternalReference(Redirect(FUNCTION_ADDR(atomic_pair_exchange)));
1228  }
1229  
atomic_pair_compare_exchange(intptr_t address,int old_value_low,int old_value_high,int new_value_low,int new_value_high)1230  static uint64_t atomic_pair_compare_exchange(intptr_t address,
1231                                               int old_value_low,
1232                                               int old_value_high,
1233                                               int new_value_low,
1234                                               int new_value_high) {
1235    uint64_t old_value = static_cast<uint64_t>(old_value_high) << 32 |
1236                         (old_value_low & 0xFFFFFFFF);
1237    uint64_t new_value = static_cast<uint64_t>(new_value_high) << 32 |
1238                         (new_value_low & 0xFFFFFFFF);
1239    std::atomic_compare_exchange_strong(
1240        reinterpret_cast<std::atomic<uint64_t>*>(address), &old_value, new_value);
1241    return old_value;
1242  }
1243  
1244  FUNCTION_REFERENCE(atomic_pair_compare_exchange_function,
1245                     atomic_pair_compare_exchange)
1246  
1247  #ifdef V8_IS_TSAN
1248  namespace {
1249  // Mimics the store in generated code by having a relaxed store to the same
1250  // address, with the same value. This is done in order for TSAN to see these
1251  // stores from generated code.
1252  // Note that {value} is an int64_t irrespective of the store size. This is on
1253  // purpose to keep the function signatures the same across stores. The
1254  // static_cast inside the method will ignore the bits which will not be stored.
tsan_relaxed_store_8_bits(Address addr,int64_t value)1255  void tsan_relaxed_store_8_bits(Address addr, int64_t value) {
1256  #if V8_TARGET_ARCH_X64
1257    base::Relaxed_Store(reinterpret_cast<base::Atomic8*>(addr),
1258                        static_cast<base::Atomic8>(value));
1259  #else
1260    UNREACHABLE();
1261  #endif  // V8_TARGET_ARCH_X64
1262  }
1263  
tsan_relaxed_store_16_bits(Address addr,int64_t value)1264  void tsan_relaxed_store_16_bits(Address addr, int64_t value) {
1265  #if V8_TARGET_ARCH_X64
1266    base::Relaxed_Store(reinterpret_cast<base::Atomic16*>(addr),
1267                        static_cast<base::Atomic16>(value));
1268  #else
1269    UNREACHABLE();
1270  #endif  // V8_TARGET_ARCH_X64
1271  }
1272  
tsan_relaxed_store_32_bits(Address addr,int64_t value)1273  void tsan_relaxed_store_32_bits(Address addr, int64_t value) {
1274  #if V8_TARGET_ARCH_X64
1275      base::Relaxed_Store(reinterpret_cast<base::Atomic32*>(addr),
1276                          static_cast<base::Atomic32>(value));
1277  #else
1278    UNREACHABLE();
1279  #endif  // V8_TARGET_ARCH_X64
1280  }
1281  
tsan_relaxed_store_64_bits(Address addr,int64_t value)1282  void tsan_relaxed_store_64_bits(Address addr, int64_t value) {
1283  #if V8_TARGET_ARCH_X64
1284    base::Relaxed_Store(reinterpret_cast<base::Atomic64*>(addr),
1285                        static_cast<base::Atomic64>(value));
1286  #else
1287    UNREACHABLE();
1288  #endif  // V8_TARGET_ARCH_X64
1289  }
1290  
1291  // Same as above, for sequentially consistent stores.
tsan_seq_cst_store_8_bits(Address addr,int64_t value)1292  void tsan_seq_cst_store_8_bits(Address addr, int64_t value) {
1293  #if V8_TARGET_ARCH_X64
1294    base::SeqCst_Store(reinterpret_cast<base::Atomic8*>(addr),
1295                       static_cast<base::Atomic8>(value));
1296  #else
1297    UNREACHABLE();
1298  #endif  // V8_TARGET_ARCH_X64
1299  }
1300  
tsan_seq_cst_store_16_bits(Address addr,int64_t value)1301  void tsan_seq_cst_store_16_bits(Address addr, int64_t value) {
1302  #if V8_TARGET_ARCH_X64
1303    base::SeqCst_Store(reinterpret_cast<base::Atomic16*>(addr),
1304                       static_cast<base::Atomic16>(value));
1305  #else
1306    UNREACHABLE();
1307  #endif  // V8_TARGET_ARCH_X64
1308  }
1309  
tsan_seq_cst_store_32_bits(Address addr,int64_t value)1310  void tsan_seq_cst_store_32_bits(Address addr, int64_t value) {
1311  #if V8_TARGET_ARCH_X64
1312    base::SeqCst_Store(reinterpret_cast<base::Atomic32*>(addr),
1313                       static_cast<base::Atomic32>(value));
1314  #else
1315    UNREACHABLE();
1316  #endif  // V8_TARGET_ARCH_X64
1317  }
1318  
tsan_seq_cst_store_64_bits(Address addr,int64_t value)1319  void tsan_seq_cst_store_64_bits(Address addr, int64_t value) {
1320  #if V8_TARGET_ARCH_X64
1321    base::SeqCst_Store(reinterpret_cast<base::Atomic64*>(addr),
1322                       static_cast<base::Atomic64>(value));
1323  #else
1324    UNREACHABLE();
1325  #endif  // V8_TARGET_ARCH_X64
1326  }
1327  
1328  // Same as above, for relaxed loads.
tsan_relaxed_load_32_bits(Address addr,int64_t value)1329  base::Atomic32 tsan_relaxed_load_32_bits(Address addr, int64_t value) {
1330  #if V8_TARGET_ARCH_X64
1331    return base::Relaxed_Load(reinterpret_cast<base::Atomic32*>(addr));
1332  #else
1333    UNREACHABLE();
1334  #endif  // V8_TARGET_ARCH_X64
1335  }
1336  
tsan_relaxed_load_64_bits(Address addr,int64_t value)1337  base::Atomic64 tsan_relaxed_load_64_bits(Address addr, int64_t value) {
1338  #if V8_TARGET_ARCH_X64
1339    return base::Relaxed_Load(reinterpret_cast<base::Atomic64*>(addr));
1340  #else
1341    UNREACHABLE();
1342  #endif  // V8_TARGET_ARCH_X64
1343  }
1344  
1345  }  // namespace
1346  #endif  // V8_IS_TSAN
1347  
IF_TSAN(FUNCTION_REFERENCE,tsan_relaxed_store_function_8_bits,tsan_relaxed_store_8_bits)1348  IF_TSAN(FUNCTION_REFERENCE, tsan_relaxed_store_function_8_bits,
1349          tsan_relaxed_store_8_bits)
1350  IF_TSAN(FUNCTION_REFERENCE, tsan_relaxed_store_function_16_bits,
1351          tsan_relaxed_store_16_bits)
1352  IF_TSAN(FUNCTION_REFERENCE, tsan_relaxed_store_function_32_bits,
1353          tsan_relaxed_store_32_bits)
1354  IF_TSAN(FUNCTION_REFERENCE, tsan_relaxed_store_function_64_bits,
1355          tsan_relaxed_store_64_bits)
1356  IF_TSAN(FUNCTION_REFERENCE, tsan_seq_cst_store_function_8_bits,
1357          tsan_seq_cst_store_8_bits)
1358  IF_TSAN(FUNCTION_REFERENCE, tsan_seq_cst_store_function_16_bits,
1359          tsan_seq_cst_store_16_bits)
1360  IF_TSAN(FUNCTION_REFERENCE, tsan_seq_cst_store_function_32_bits,
1361          tsan_seq_cst_store_32_bits)
1362  IF_TSAN(FUNCTION_REFERENCE, tsan_seq_cst_store_function_64_bits,
1363          tsan_seq_cst_store_64_bits)
1364  IF_TSAN(FUNCTION_REFERENCE, tsan_relaxed_load_function_32_bits,
1365          tsan_relaxed_load_32_bits)
1366  IF_TSAN(FUNCTION_REFERENCE, tsan_relaxed_load_function_64_bits,
1367          tsan_relaxed_load_64_bits)
1368  
1369  static int EnterMicrotaskContextWrapper(HandleScopeImplementer* hsi,
1370                                          Address raw_context) {
1371    Context context = Context::cast(Object(raw_context));
1372    hsi->EnterMicrotaskContext(context);
1373    return 0;
1374  }
1375  
1376  FUNCTION_REFERENCE(call_enter_context_function, EnterMicrotaskContextWrapper)
1377  
1378  FUNCTION_REFERENCE(
1379      js_finalization_registry_remove_cell_from_unregister_token_map,
1380      JSFinalizationRegistry::RemoveCellFromUnregisterTokenMap)
1381  
1382  #ifdef V8_SANDBOXED_EXTERNAL_POINTERS
1383  FUNCTION_REFERENCE(external_pointer_table_allocate_entry,
1384                     ExternalPointerTable::AllocateEntry)
1385  #endif
1386  
1387  bool operator==(ExternalReference lhs, ExternalReference rhs) {
1388    return lhs.address() == rhs.address();
1389  }
1390  
operator !=(ExternalReference lhs,ExternalReference rhs)1391  bool operator!=(ExternalReference lhs, ExternalReference rhs) {
1392    return !(lhs == rhs);
1393  }
1394  
hash_value(ExternalReference reference)1395  size_t hash_value(ExternalReference reference) {
1396    if (FLAG_predictable) {
1397      // Avoid ASLR non-determinism in predictable mode. For this, just take the
1398      // lowest 12 bit corresponding to a 4K page size.
1399      return base::hash<Address>()(reference.address() & 0xfff);
1400    }
1401    return base::hash<Address>()(reference.address());
1402  }
1403  
operator <<(std::ostream & os,ExternalReference reference)1404  std::ostream& operator<<(std::ostream& os, ExternalReference reference) {
1405    os << reinterpret_cast<const void*>(reference.address());
1406    const Runtime::Function* fn = Runtime::FunctionForEntry(reference.address());
1407    if (fn) os << "<" << fn->name << ".entry>";
1408    return os;
1409  }
1410  
abort_with_reason(int reason)1411  void abort_with_reason(int reason) {
1412    if (IsValidAbortReason(reason)) {
1413      const char* message = GetAbortReason(static_cast<AbortReason>(reason));
1414      base::OS::PrintError("abort: %s\n", message);
1415    } else {
1416      base::OS::PrintError("abort: <unknown reason: %d>\n", reason);
1417    }
1418    base::OS::Abort();
1419    UNREACHABLE();
1420  }
1421  
1422  #undef FUNCTION_REFERENCE
1423  #undef FUNCTION_REFERENCE_WITH_TYPE
1424  
1425  }  // namespace internal
1426  }  // namespace v8
1427