• 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