Home | History | Annotate | Download | only in src
      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/external-reference.h"
      6 
      7 #include "src/api.h"
      8 #include "src/base/ieee754.h"
      9 #include "src/codegen.h"
     10 #include "src/compiler/code-assembler.h"
     11 #include "src/counters.h"
     12 #include "src/debug/debug.h"
     13 #include "src/deoptimizer.h"
     14 #include "src/elements.h"
     15 #include "src/heap/heap.h"
     16 #include "src/ic/stub-cache.h"
     17 #include "src/interpreter/interpreter.h"
     18 #include "src/isolate.h"
     19 #include "src/objects-inl.h"
     20 #include "src/regexp/regexp-stack.h"
     21 #include "src/simulator-base.h"
     22 #include "src/string-search.h"
     23 #include "src/wasm/wasm-external-refs.h"
     24 
     25 // Include native regexp-macro-assembler.
     26 #ifndef V8_INTERPRETED_REGEXP
     27 #if V8_TARGET_ARCH_IA32
     28 #include "src/regexp/ia32/regexp-macro-assembler-ia32.h"  // NOLINT
     29 #elif V8_TARGET_ARCH_X64
     30 #include "src/regexp/x64/regexp-macro-assembler-x64.h"  // NOLINT
     31 #elif V8_TARGET_ARCH_ARM64
     32 #include "src/regexp/arm64/regexp-macro-assembler-arm64.h"  // NOLINT
     33 #elif V8_TARGET_ARCH_ARM
     34 #include "src/regexp/arm/regexp-macro-assembler-arm.h"  // NOLINT
     35 #elif V8_TARGET_ARCH_PPC
     36 #include "src/regexp/ppc/regexp-macro-assembler-ppc.h"  // NOLINT
     37 #elif V8_TARGET_ARCH_MIPS
     38 #include "src/regexp/mips/regexp-macro-assembler-mips.h"  // NOLINT
     39 #elif V8_TARGET_ARCH_MIPS64
     40 #include "src/regexp/mips64/regexp-macro-assembler-mips64.h"  // NOLINT
     41 #elif V8_TARGET_ARCH_S390
     42 #include "src/regexp/s390/regexp-macro-assembler-s390.h"  // NOLINT
     43 #else  // Unknown architecture.
     44 #error "Unknown architecture."
     45 #endif  // Target architecture.
     46 #endif  // V8_INTERPRETED_REGEXP
     47 
     48 #ifdef V8_INTL_SUPPORT
     49 #include "src/intl.h"
     50 #endif  // V8_INTL_SUPPORT
     51 
     52 namespace v8 {
     53 namespace internal {
     54 
     55 // -----------------------------------------------------------------------------
     56 // Common double constants.
     57 
     58 constexpr double double_min_int_constant = kMinInt;
     59 constexpr double double_one_half_constant = 0.5;
     60 constexpr uint64_t double_the_hole_nan_constant = kHoleNanInt64;
     61 constexpr double double_uint32_bias_constant =
     62     static_cast<double>(kMaxUInt32) + 1;
     63 
     64 constexpr struct V8_ALIGNED(16) {
     65   uint32_t a;
     66   uint32_t b;
     67   uint32_t c;
     68   uint32_t d;
     69 } float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
     70 
     71 constexpr struct V8_ALIGNED(16) {
     72   uint32_t a;
     73   uint32_t b;
     74   uint32_t c;
     75   uint32_t d;
     76 } float_negate_constant = {0x80000000, 0x80000000, 0x80000000, 0x80000000};
     77 
     78 constexpr struct V8_ALIGNED(16) {
     79   uint64_t a;
     80   uint64_t b;
     81 } double_absolute_constant = {uint64_t{0x7FFFFFFFFFFFFFFF},
     82                               uint64_t{0x7FFFFFFFFFFFFFFF}};
     83 
     84 constexpr struct V8_ALIGNED(16) {
     85   uint64_t a;
     86   uint64_t b;
     87 } double_negate_constant = {uint64_t{0x8000000000000000},
     88                             uint64_t{0x8000000000000000}};
     89 
     90 // Implementation of ExternalReference
     91 
     92 static ExternalReference::Type BuiltinCallTypeForResultSize(int result_size) {
     93   switch (result_size) {
     94     case 1:
     95       return ExternalReference::BUILTIN_CALL;
     96     case 2:
     97       return ExternalReference::BUILTIN_CALL_PAIR;
     98   }
     99   UNREACHABLE();
    100 }
    101 
    102 // static
    103 ExternalReference ExternalReference::Create(
    104     ApiFunction* fun, Type type = ExternalReference::BUILTIN_CALL) {
    105   return ExternalReference(Redirect(fun->address(), type));
    106 }
    107 
    108 // static
    109 ExternalReference ExternalReference::Create(Runtime::FunctionId id) {
    110   return Create(Runtime::FunctionForId(id));
    111 }
    112 
    113 // static
    114 ExternalReference ExternalReference::Create(const Runtime::Function* f) {
    115   return ExternalReference(
    116       Redirect(f->entry, BuiltinCallTypeForResultSize(f->result_size)));
    117 }
    118 
    119 // static
    120 ExternalReference ExternalReference::Create(Address address) {
    121   return ExternalReference(Redirect(address));
    122 }
    123 
    124 ExternalReference ExternalReference::isolate_address(Isolate* isolate) {
    125   return ExternalReference(isolate);
    126 }
    127 
    128 ExternalReference ExternalReference::builtins_address(Isolate* isolate) {
    129   return ExternalReference(isolate->heap()->builtin_address(0));
    130 }
    131 
    132 ExternalReference ExternalReference::handle_scope_implementer_address(
    133     Isolate* isolate) {
    134   return ExternalReference(isolate->handle_scope_implementer_address());
    135 }
    136 
    137 ExternalReference ExternalReference::pending_microtask_count_address(
    138     Isolate* isolate) {
    139   return ExternalReference(isolate->pending_microtask_count_address());
    140 }
    141 
    142 ExternalReference ExternalReference::interpreter_dispatch_table_address(
    143     Isolate* isolate) {
    144   return ExternalReference(isolate->interpreter()->dispatch_table_address());
    145 }
    146 
    147 ExternalReference ExternalReference::interpreter_dispatch_counters(
    148     Isolate* isolate) {
    149   return ExternalReference(
    150       isolate->interpreter()->bytecode_dispatch_counters_table());
    151 }
    152 
    153 ExternalReference ExternalReference::bytecode_size_table_address() {
    154   return ExternalReference(
    155       interpreter::Bytecodes::bytecode_size_table_address());
    156 }
    157 
    158 // static
    159 ExternalReference ExternalReference::Create(StatsCounter* counter) {
    160   return ExternalReference(
    161       reinterpret_cast<Address>(counter->GetInternalPointer()));
    162 }
    163 
    164 // static
    165 ExternalReference ExternalReference::Create(IsolateAddressId id,
    166                                             Isolate* isolate) {
    167   return ExternalReference(isolate->get_address_from_id(id));
    168 }
    169 
    170 // static
    171 ExternalReference ExternalReference::Create(const SCTableReference& table_ref) {
    172   return ExternalReference(table_ref.address());
    173 }
    174 
    175 ExternalReference
    176 ExternalReference::incremental_marking_record_write_function() {
    177   return ExternalReference(
    178       Redirect(FUNCTION_ADDR(IncrementalMarking::RecordWriteFromCode)));
    179 }
    180 
    181 ExternalReference ExternalReference::store_buffer_overflow_function() {
    182   return ExternalReference(
    183       Redirect(Heap::store_buffer_overflow_function_address()));
    184 }
    185 
    186 ExternalReference ExternalReference::delete_handle_scope_extensions() {
    187   return ExternalReference(
    188       Redirect(FUNCTION_ADDR(HandleScope::DeleteExtensions)));
    189 }
    190 
    191 ExternalReference ExternalReference::get_date_field_function() {
    192   return ExternalReference(Redirect(FUNCTION_ADDR(JSDate::GetField)));
    193 }
    194 
    195 ExternalReference ExternalReference::date_cache_stamp(Isolate* isolate) {
    196   return ExternalReference(isolate->date_cache()->stamp_address());
    197 }
    198 
    199 // static
    200 ExternalReference
    201 ExternalReference::runtime_function_table_address_for_unittests(
    202     Isolate* isolate) {
    203   return runtime_function_table_address(isolate);
    204 }
    205 
    206 // static
    207 Address ExternalReference::Redirect(Address address, Type type) {
    208 #ifdef USE_SIMULATOR
    209   return SimulatorBase::RedirectExternalReference(address, type);
    210 #else
    211   return address;
    212 #endif
    213 }
    214 
    215 ExternalReference ExternalReference::stress_deopt_count(Isolate* isolate) {
    216   return ExternalReference(isolate->stress_deopt_count_address());
    217 }
    218 
    219 ExternalReference ExternalReference::force_slow_path(Isolate* isolate) {
    220   return ExternalReference(isolate->force_slow_path_address());
    221 }
    222 
    223 ExternalReference ExternalReference::new_deoptimizer_function() {
    224   return ExternalReference(Redirect(FUNCTION_ADDR(Deoptimizer::New)));
    225 }
    226 
    227 ExternalReference ExternalReference::compute_output_frames_function() {
    228   return ExternalReference(
    229       Redirect(FUNCTION_ADDR(Deoptimizer::ComputeOutputFrames)));
    230 }
    231 
    232 ExternalReference ExternalReference::wasm_f32_trunc() {
    233   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f32_trunc_wrapper)));
    234 }
    235 ExternalReference ExternalReference::wasm_f32_floor() {
    236   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f32_floor_wrapper)));
    237 }
    238 ExternalReference ExternalReference::wasm_f32_ceil() {
    239   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f32_ceil_wrapper)));
    240 }
    241 ExternalReference ExternalReference::wasm_f32_nearest_int() {
    242   return ExternalReference(
    243       Redirect(FUNCTION_ADDR(wasm::f32_nearest_int_wrapper)));
    244 }
    245 
    246 ExternalReference ExternalReference::wasm_f64_trunc() {
    247   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f64_trunc_wrapper)));
    248 }
    249 
    250 ExternalReference ExternalReference::wasm_f64_floor() {
    251   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f64_floor_wrapper)));
    252 }
    253 
    254 ExternalReference ExternalReference::wasm_f64_ceil() {
    255   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f64_ceil_wrapper)));
    256 }
    257 
    258 ExternalReference ExternalReference::wasm_f64_nearest_int() {
    259   return ExternalReference(
    260       Redirect(FUNCTION_ADDR(wasm::f64_nearest_int_wrapper)));
    261 }
    262 
    263 ExternalReference ExternalReference::wasm_int64_to_float32() {
    264   return ExternalReference(
    265       Redirect(FUNCTION_ADDR(wasm::int64_to_float32_wrapper)));
    266 }
    267 
    268 ExternalReference ExternalReference::wasm_uint64_to_float32() {
    269   return ExternalReference(
    270       Redirect(FUNCTION_ADDR(wasm::uint64_to_float32_wrapper)));
    271 }
    272 
    273 ExternalReference ExternalReference::wasm_int64_to_float64() {
    274   return ExternalReference(
    275       Redirect(FUNCTION_ADDR(wasm::int64_to_float64_wrapper)));
    276 }
    277 
    278 ExternalReference ExternalReference::wasm_uint64_to_float64() {
    279   return ExternalReference(
    280       Redirect(FUNCTION_ADDR(wasm::uint64_to_float64_wrapper)));
    281 }
    282 
    283 ExternalReference ExternalReference::wasm_float32_to_int64() {
    284   return ExternalReference(
    285       Redirect(FUNCTION_ADDR(wasm::float32_to_int64_wrapper)));
    286 }
    287 
    288 ExternalReference ExternalReference::wasm_float32_to_uint64() {
    289   return ExternalReference(
    290       Redirect(FUNCTION_ADDR(wasm::float32_to_uint64_wrapper)));
    291 }
    292 
    293 ExternalReference ExternalReference::wasm_float64_to_int64() {
    294   return ExternalReference(
    295       Redirect(FUNCTION_ADDR(wasm::float64_to_int64_wrapper)));
    296 }
    297 
    298 ExternalReference ExternalReference::wasm_float64_to_uint64() {
    299   return ExternalReference(
    300       Redirect(FUNCTION_ADDR(wasm::float64_to_uint64_wrapper)));
    301 }
    302 
    303 ExternalReference ExternalReference::wasm_int64_div() {
    304   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::int64_div_wrapper)));
    305 }
    306 
    307 ExternalReference ExternalReference::wasm_int64_mod() {
    308   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::int64_mod_wrapper)));
    309 }
    310 
    311 ExternalReference ExternalReference::wasm_uint64_div() {
    312   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::uint64_div_wrapper)));
    313 }
    314 
    315 ExternalReference ExternalReference::wasm_uint64_mod() {
    316   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::uint64_mod_wrapper)));
    317 }
    318 
    319 ExternalReference ExternalReference::wasm_word32_ctz() {
    320   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word32_ctz_wrapper)));
    321 }
    322 
    323 ExternalReference ExternalReference::wasm_word64_ctz() {
    324   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word64_ctz_wrapper)));
    325 }
    326 
    327 ExternalReference ExternalReference::wasm_word32_popcnt() {
    328   return ExternalReference(
    329       Redirect(FUNCTION_ADDR(wasm::word32_popcnt_wrapper)));
    330 }
    331 
    332 ExternalReference ExternalReference::wasm_word64_popcnt() {
    333   return ExternalReference(
    334       Redirect(FUNCTION_ADDR(wasm::word64_popcnt_wrapper)));
    335 }
    336 
    337 ExternalReference ExternalReference::wasm_word32_rol() {
    338   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word32_rol_wrapper)));
    339 }
    340 
    341 ExternalReference ExternalReference::wasm_word32_ror() {
    342   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word32_ror_wrapper)));
    343 }
    344 
    345 static void f64_acos_wrapper(Address data) {
    346   double input = ReadUnalignedValue<double>(data);
    347   WriteUnalignedValue(data, base::ieee754::acos(input));
    348 }
    349 
    350 ExternalReference ExternalReference::f64_acos_wrapper_function() {
    351   return ExternalReference(Redirect(FUNCTION_ADDR(f64_acos_wrapper)));
    352 }
    353 
    354 static void f64_asin_wrapper(Address data) {
    355   double input = ReadUnalignedValue<double>(data);
    356   WriteUnalignedValue<double>(data, base::ieee754::asin(input));
    357 }
    358 
    359 ExternalReference ExternalReference::f64_asin_wrapper_function() {
    360   return ExternalReference(Redirect(FUNCTION_ADDR(f64_asin_wrapper)));
    361 }
    362 
    363 ExternalReference ExternalReference::wasm_float64_pow() {
    364   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::float64_pow_wrapper)));
    365 }
    366 
    367 static void f64_mod_wrapper(Address data) {
    368   double dividend = ReadUnalignedValue<double>(data);
    369   double divisor = ReadUnalignedValue<double>(data + sizeof(dividend));
    370   WriteUnalignedValue<double>(data, Modulo(dividend, divisor));
    371 }
    372 
    373 ExternalReference ExternalReference::f64_mod_wrapper_function() {
    374   return ExternalReference(Redirect(FUNCTION_ADDR(f64_mod_wrapper)));
    375 }
    376 
    377 ExternalReference ExternalReference::wasm_call_trap_callback_for_testing() {
    378   return ExternalReference(
    379       Redirect(FUNCTION_ADDR(wasm::call_trap_callback_for_testing)));
    380 }
    381 
    382 ExternalReference ExternalReference::log_enter_external_function() {
    383   return ExternalReference(Redirect(FUNCTION_ADDR(Logger::EnterExternal)));
    384 }
    385 
    386 ExternalReference ExternalReference::log_leave_external_function() {
    387   return ExternalReference(Redirect(FUNCTION_ADDR(Logger::LeaveExternal)));
    388 }
    389 
    390 ExternalReference ExternalReference::roots_array_start(Isolate* isolate) {
    391   return ExternalReference(isolate->heap()->roots_array_start());
    392 }
    393 
    394 ExternalReference ExternalReference::allocation_sites_list_address(
    395     Isolate* isolate) {
    396   return ExternalReference(isolate->heap()->allocation_sites_list_address());
    397 }
    398 
    399 ExternalReference ExternalReference::address_of_stack_limit(Isolate* isolate) {
    400   return ExternalReference(isolate->stack_guard()->address_of_jslimit());
    401 }
    402 
    403 ExternalReference ExternalReference::address_of_real_stack_limit(
    404     Isolate* isolate) {
    405   return ExternalReference(isolate->stack_guard()->address_of_real_jslimit());
    406 }
    407 
    408 ExternalReference ExternalReference::store_buffer_top(Isolate* isolate) {
    409   return ExternalReference(isolate->heap()->store_buffer_top_address());
    410 }
    411 
    412 ExternalReference ExternalReference::heap_is_marking_flag_address(
    413     Isolate* isolate) {
    414   return ExternalReference(isolate->heap()->IsMarkingFlagAddress());
    415 }
    416 
    417 ExternalReference ExternalReference::new_space_allocation_top_address(
    418     Isolate* isolate) {
    419   return ExternalReference(isolate->heap()->NewSpaceAllocationTopAddress());
    420 }
    421 
    422 ExternalReference ExternalReference::new_space_allocation_limit_address(
    423     Isolate* isolate) {
    424   return ExternalReference(isolate->heap()->NewSpaceAllocationLimitAddress());
    425 }
    426 
    427 ExternalReference ExternalReference::old_space_allocation_top_address(
    428     Isolate* isolate) {
    429   return ExternalReference(isolate->heap()->OldSpaceAllocationTopAddress());
    430 }
    431 
    432 ExternalReference ExternalReference::old_space_allocation_limit_address(
    433     Isolate* isolate) {
    434   return ExternalReference(isolate->heap()->OldSpaceAllocationLimitAddress());
    435 }
    436 
    437 ExternalReference ExternalReference::handle_scope_level_address(
    438     Isolate* isolate) {
    439   return ExternalReference(HandleScope::current_level_address(isolate));
    440 }
    441 
    442 ExternalReference ExternalReference::handle_scope_next_address(
    443     Isolate* isolate) {
    444   return ExternalReference(HandleScope::current_next_address(isolate));
    445 }
    446 
    447 ExternalReference ExternalReference::handle_scope_limit_address(
    448     Isolate* isolate) {
    449   return ExternalReference(HandleScope::current_limit_address(isolate));
    450 }
    451 
    452 ExternalReference ExternalReference::scheduled_exception_address(
    453     Isolate* isolate) {
    454   return ExternalReference(isolate->scheduled_exception_address());
    455 }
    456 
    457 ExternalReference ExternalReference::address_of_pending_message_obj(
    458     Isolate* isolate) {
    459   return ExternalReference(isolate->pending_message_obj_address());
    460 }
    461 
    462 ExternalReference ExternalReference::abort_with_reason() {
    463   return ExternalReference(Redirect(FUNCTION_ADDR(i::abort_with_reason)));
    464 }
    465 
    466 ExternalReference ExternalReference::address_of_min_int() {
    467   return ExternalReference(reinterpret_cast<Address>(&double_min_int_constant));
    468 }
    469 
    470 ExternalReference ExternalReference::address_of_runtime_stats_flag() {
    471   return ExternalReference(&FLAG_runtime_stats);
    472 }
    473 
    474 ExternalReference ExternalReference::address_of_one_half() {
    475   return ExternalReference(
    476       reinterpret_cast<Address>(&double_one_half_constant));
    477 }
    478 
    479 ExternalReference ExternalReference::address_of_the_hole_nan() {
    480   return ExternalReference(
    481       reinterpret_cast<Address>(&double_the_hole_nan_constant));
    482 }
    483 
    484 ExternalReference ExternalReference::address_of_uint32_bias() {
    485   return ExternalReference(
    486       reinterpret_cast<Address>(&double_uint32_bias_constant));
    487 }
    488 
    489 ExternalReference ExternalReference::address_of_float_abs_constant() {
    490   return ExternalReference(reinterpret_cast<Address>(&float_absolute_constant));
    491 }
    492 
    493 ExternalReference ExternalReference::address_of_float_neg_constant() {
    494   return ExternalReference(reinterpret_cast<Address>(&float_negate_constant));
    495 }
    496 
    497 ExternalReference ExternalReference::address_of_double_abs_constant() {
    498   return ExternalReference(
    499       reinterpret_cast<Address>(&double_absolute_constant));
    500 }
    501 
    502 ExternalReference ExternalReference::address_of_double_neg_constant() {
    503   return ExternalReference(reinterpret_cast<Address>(&double_negate_constant));
    504 }
    505 
    506 ExternalReference ExternalReference::is_profiling_address(Isolate* isolate) {
    507   return ExternalReference(isolate->is_profiling_address());
    508 }
    509 
    510 ExternalReference ExternalReference::invoke_function_callback() {
    511   Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
    512   ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
    513   ApiFunction thunk_fun(thunk_address);
    514   return ExternalReference::Create(&thunk_fun, thunk_type);
    515 }
    516 
    517 ExternalReference ExternalReference::invoke_accessor_getter_callback() {
    518   Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
    519   ExternalReference::Type thunk_type = ExternalReference::PROFILING_GETTER_CALL;
    520   ApiFunction thunk_fun(thunk_address);
    521   return ExternalReference::Create(&thunk_fun, thunk_type);
    522 }
    523 
    524 #ifndef V8_INTERPRETED_REGEXP
    525 
    526 ExternalReference ExternalReference::re_check_stack_guard_state(
    527     Isolate* isolate) {
    528   Address function;
    529 #if V8_TARGET_ARCH_X64
    530   function = FUNCTION_ADDR(RegExpMacroAssemblerX64::CheckStackGuardState);
    531 #elif V8_TARGET_ARCH_IA32
    532   function = FUNCTION_ADDR(RegExpMacroAssemblerIA32::CheckStackGuardState);
    533 #elif V8_TARGET_ARCH_ARM64
    534   function = FUNCTION_ADDR(RegExpMacroAssemblerARM64::CheckStackGuardState);
    535 #elif V8_TARGET_ARCH_ARM
    536   function = FUNCTION_ADDR(RegExpMacroAssemblerARM::CheckStackGuardState);
    537 #elif V8_TARGET_ARCH_PPC
    538   function = FUNCTION_ADDR(RegExpMacroAssemblerPPC::CheckStackGuardState);
    539 #elif V8_TARGET_ARCH_MIPS
    540   function = FUNCTION_ADDR(RegExpMacroAssemblerMIPS::CheckStackGuardState);
    541 #elif V8_TARGET_ARCH_MIPS64
    542   function = FUNCTION_ADDR(RegExpMacroAssemblerMIPS::CheckStackGuardState);
    543 #elif V8_TARGET_ARCH_S390
    544   function = FUNCTION_ADDR(RegExpMacroAssemblerS390::CheckStackGuardState);
    545 #else
    546   UNREACHABLE();
    547 #endif
    548   return ExternalReference(Redirect(function));
    549 }
    550 
    551 ExternalReference ExternalReference::re_grow_stack(Isolate* isolate) {
    552   return ExternalReference(
    553       Redirect(FUNCTION_ADDR(NativeRegExpMacroAssembler::GrowStack)));
    554 }
    555 
    556 ExternalReference ExternalReference::re_case_insensitive_compare_uc16(
    557     Isolate* isolate) {
    558   return ExternalReference(Redirect(
    559       FUNCTION_ADDR(NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16)));
    560 }
    561 
    562 ExternalReference ExternalReference::re_word_character_map(Isolate* isolate) {
    563   return ExternalReference(
    564       NativeRegExpMacroAssembler::word_character_map_address());
    565 }
    566 
    567 ExternalReference ExternalReference::address_of_static_offsets_vector(
    568     Isolate* isolate) {
    569   return ExternalReference(
    570       reinterpret_cast<Address>(isolate->jsregexp_static_offsets_vector()));
    571 }
    572 
    573 ExternalReference ExternalReference::address_of_regexp_stack_limit(
    574     Isolate* isolate) {
    575   return ExternalReference(isolate->regexp_stack()->limit_address());
    576 }
    577 
    578 ExternalReference ExternalReference::address_of_regexp_stack_memory_address(
    579     Isolate* isolate) {
    580   return ExternalReference(isolate->regexp_stack()->memory_address());
    581 }
    582 
    583 ExternalReference ExternalReference::address_of_regexp_stack_memory_size(
    584     Isolate* isolate) {
    585   return ExternalReference(isolate->regexp_stack()->memory_size_address());
    586 }
    587 
    588 #endif  // V8_INTERPRETED_REGEXP
    589 
    590 ExternalReference ExternalReference::ieee754_acos_function() {
    591   return ExternalReference(
    592       Redirect(FUNCTION_ADDR(base::ieee754::acos), BUILTIN_FP_CALL));
    593 }
    594 
    595 ExternalReference ExternalReference::ieee754_acosh_function() {
    596   return ExternalReference(
    597       Redirect(FUNCTION_ADDR(base::ieee754::acosh), BUILTIN_FP_FP_CALL));
    598 }
    599 
    600 ExternalReference ExternalReference::ieee754_asin_function() {
    601   return ExternalReference(
    602       Redirect(FUNCTION_ADDR(base::ieee754::asin), BUILTIN_FP_CALL));
    603 }
    604 
    605 ExternalReference ExternalReference::ieee754_asinh_function() {
    606   return ExternalReference(
    607       Redirect(FUNCTION_ADDR(base::ieee754::asinh), BUILTIN_FP_FP_CALL));
    608 }
    609 
    610 ExternalReference ExternalReference::ieee754_atan_function() {
    611   return ExternalReference(
    612       Redirect(FUNCTION_ADDR(base::ieee754::atan), BUILTIN_FP_CALL));
    613 }
    614 
    615 ExternalReference ExternalReference::ieee754_atanh_function() {
    616   return ExternalReference(
    617       Redirect(FUNCTION_ADDR(base::ieee754::atanh), BUILTIN_FP_FP_CALL));
    618 }
    619 
    620 ExternalReference ExternalReference::ieee754_atan2_function() {
    621   return ExternalReference(
    622       Redirect(FUNCTION_ADDR(base::ieee754::atan2), BUILTIN_FP_FP_CALL));
    623 }
    624 
    625 ExternalReference ExternalReference::ieee754_cbrt_function() {
    626   return ExternalReference(
    627       Redirect(FUNCTION_ADDR(base::ieee754::cbrt), BUILTIN_FP_FP_CALL));
    628 }
    629 
    630 ExternalReference ExternalReference::ieee754_cos_function() {
    631   return ExternalReference(
    632       Redirect(FUNCTION_ADDR(base::ieee754::cos), BUILTIN_FP_CALL));
    633 }
    634 
    635 ExternalReference ExternalReference::ieee754_cosh_function() {
    636   return ExternalReference(
    637       Redirect(FUNCTION_ADDR(base::ieee754::cosh), BUILTIN_FP_CALL));
    638 }
    639 
    640 ExternalReference ExternalReference::ieee754_exp_function() {
    641   return ExternalReference(
    642       Redirect(FUNCTION_ADDR(base::ieee754::exp), BUILTIN_FP_CALL));
    643 }
    644 
    645 ExternalReference ExternalReference::ieee754_expm1_function() {
    646   return ExternalReference(
    647       Redirect(FUNCTION_ADDR(base::ieee754::expm1), BUILTIN_FP_FP_CALL));
    648 }
    649 
    650 ExternalReference ExternalReference::ieee754_log_function() {
    651   return ExternalReference(
    652       Redirect(FUNCTION_ADDR(base::ieee754::log), BUILTIN_FP_CALL));
    653 }
    654 
    655 ExternalReference ExternalReference::ieee754_log1p_function() {
    656   return ExternalReference(
    657       Redirect(FUNCTION_ADDR(base::ieee754::log1p), BUILTIN_FP_CALL));
    658 }
    659 
    660 ExternalReference ExternalReference::ieee754_log10_function() {
    661   return ExternalReference(
    662       Redirect(FUNCTION_ADDR(base::ieee754::log10), BUILTIN_FP_CALL));
    663 }
    664 
    665 ExternalReference ExternalReference::ieee754_log2_function() {
    666   return ExternalReference(
    667       Redirect(FUNCTION_ADDR(base::ieee754::log2), BUILTIN_FP_CALL));
    668 }
    669 
    670 ExternalReference ExternalReference::ieee754_sin_function() {
    671   return ExternalReference(
    672       Redirect(FUNCTION_ADDR(base::ieee754::sin), BUILTIN_FP_CALL));
    673 }
    674 
    675 ExternalReference ExternalReference::ieee754_sinh_function() {
    676   return ExternalReference(
    677       Redirect(FUNCTION_ADDR(base::ieee754::sinh), BUILTIN_FP_CALL));
    678 }
    679 
    680 ExternalReference ExternalReference::ieee754_tan_function() {
    681   return ExternalReference(
    682       Redirect(FUNCTION_ADDR(base::ieee754::tan), BUILTIN_FP_CALL));
    683 }
    684 
    685 ExternalReference ExternalReference::ieee754_tanh_function() {
    686   return ExternalReference(
    687       Redirect(FUNCTION_ADDR(base::ieee754::tanh), BUILTIN_FP_CALL));
    688 }
    689 
    690 void* libc_memchr(void* string, int character, size_t search_length) {
    691   return memchr(string, character, search_length);
    692 }
    693 
    694 ExternalReference ExternalReference::libc_memchr_function() {
    695   return ExternalReference(Redirect(FUNCTION_ADDR(libc_memchr)));
    696 }
    697 
    698 void* libc_memcpy(void* dest, const void* src, size_t n) {
    699   return memcpy(dest, src, n);
    700 }
    701 
    702 ExternalReference ExternalReference::libc_memcpy_function() {
    703   return ExternalReference(Redirect(FUNCTION_ADDR(libc_memcpy)));
    704 }
    705 
    706 void* libc_memmove(void* dest, const void* src, size_t n) {
    707   return memmove(dest, src, n);
    708 }
    709 
    710 ExternalReference ExternalReference::libc_memmove_function() {
    711   return ExternalReference(Redirect(FUNCTION_ADDR(libc_memmove)));
    712 }
    713 
    714 void* libc_memset(void* dest, int value, size_t n) {
    715   DCHECK_EQ(static_cast<byte>(value), value);
    716   return memset(dest, value, n);
    717 }
    718 
    719 ExternalReference ExternalReference::libc_memset_function() {
    720   return ExternalReference(Redirect(FUNCTION_ADDR(libc_memset)));
    721 }
    722 
    723 ExternalReference ExternalReference::printf_function() {
    724   return ExternalReference(Redirect(FUNCTION_ADDR(std::printf)));
    725 }
    726 
    727 template <typename SubjectChar, typename PatternChar>
    728 ExternalReference ExternalReference::search_string_raw() {
    729   auto f = SearchStringRaw<SubjectChar, PatternChar>;
    730   return ExternalReference(Redirect(FUNCTION_ADDR(f)));
    731 }
    732 
    733 ExternalReference ExternalReference::search_string_raw_one_one() {
    734   return search_string_raw<const uint8_t, const uint8_t>();
    735 }
    736 
    737 ExternalReference ExternalReference::search_string_raw_one_two() {
    738   return search_string_raw<const uint8_t, const uc16>();
    739 }
    740 
    741 ExternalReference ExternalReference::search_string_raw_two_one() {
    742   return search_string_raw<const uc16, const uint8_t>();
    743 }
    744 
    745 ExternalReference ExternalReference::search_string_raw_two_two() {
    746   return search_string_raw<const uc16, const uc16>();
    747 }
    748 
    749 ExternalReference ExternalReference::orderedhashmap_gethash_raw() {
    750   auto f = OrderedHashMap::GetHash;
    751   return ExternalReference(Redirect(FUNCTION_ADDR(f)));
    752 }
    753 
    754 ExternalReference ExternalReference::get_or_create_hash_raw(Isolate* isolate) {
    755   typedef Smi* (*GetOrCreateHash)(Isolate * isolate, Object * key);
    756   GetOrCreateHash f = Object::GetOrCreateHash;
    757   return ExternalReference(Redirect(FUNCTION_ADDR(f)));
    758 }
    759 
    760 ExternalReference ExternalReference::jsreceiver_create_identity_hash(
    761     Isolate* isolate) {
    762   typedef Smi* (*CreateIdentityHash)(Isolate * isolate, JSReceiver * key);
    763   CreateIdentityHash f = JSReceiver::CreateIdentityHash;
    764   return ExternalReference(Redirect(FUNCTION_ADDR(f)));
    765 }
    766 
    767 ExternalReference
    768 ExternalReference::copy_fast_number_jsarray_elements_to_typed_array() {
    769   return ExternalReference(
    770       Redirect(FUNCTION_ADDR(CopyFastNumberJSArrayElementsToTypedArray)));
    771 }
    772 
    773 ExternalReference
    774 ExternalReference::copy_typed_array_elements_to_typed_array() {
    775   return ExternalReference(
    776       Redirect(FUNCTION_ADDR(CopyTypedArrayElementsToTypedArray)));
    777 }
    778 
    779 ExternalReference ExternalReference::copy_typed_array_elements_slice() {
    780   return ExternalReference(
    781       Redirect(FUNCTION_ADDR(CopyTypedArrayElementsSlice)));
    782 }
    783 
    784 ExternalReference ExternalReference::try_internalize_string_function() {
    785   return ExternalReference(
    786       Redirect(FUNCTION_ADDR(StringTable::LookupStringIfExists_NoAllocate)));
    787 }
    788 
    789 ExternalReference ExternalReference::check_object_type() {
    790   return ExternalReference(Redirect(FUNCTION_ADDR(CheckObjectType)));
    791 }
    792 
    793 #ifdef V8_INTL_SUPPORT
    794 ExternalReference ExternalReference::intl_convert_one_byte_to_lower() {
    795   return ExternalReference(Redirect(FUNCTION_ADDR(ConvertOneByteToLower)));
    796 }
    797 
    798 ExternalReference ExternalReference::intl_to_latin1_lower_table() {
    799   uint8_t* ptr = const_cast<uint8_t*>(ToLatin1LowerTable());
    800   return ExternalReference(reinterpret_cast<Address>(ptr));
    801 }
    802 #endif  // V8_INTL_SUPPORT
    803 
    804 // Explicit instantiations for all combinations of 1- and 2-byte strings.
    805 template ExternalReference
    806 ExternalReference::search_string_raw<const uint8_t, const uint8_t>();
    807 template ExternalReference
    808 ExternalReference::search_string_raw<const uint8_t, const uc16>();
    809 template ExternalReference
    810 ExternalReference::search_string_raw<const uc16, const uint8_t>();
    811 template ExternalReference
    812 ExternalReference::search_string_raw<const uc16, const uc16>();
    813 
    814 ExternalReference ExternalReference::page_flags(Page* page) {
    815   return ExternalReference(reinterpret_cast<Address>(page) +
    816                            MemoryChunk::kFlagsOffset);
    817 }
    818 
    819 ExternalReference ExternalReference::ForDeoptEntry(Address entry) {
    820   return ExternalReference(entry);
    821 }
    822 
    823 ExternalReference ExternalReference::cpu_features() {
    824   DCHECK(CpuFeatures::initialized_);
    825   return ExternalReference(&CpuFeatures::supported_);
    826 }
    827 
    828 ExternalReference ExternalReference::promise_hook_address(Isolate* isolate) {
    829   return ExternalReference(isolate->promise_hook_address());
    830 }
    831 
    832 ExternalReference ExternalReference::async_event_delegate_address(
    833     Isolate* isolate) {
    834   return ExternalReference(isolate->async_event_delegate_address());
    835 }
    836 
    837 ExternalReference
    838 ExternalReference::promise_hook_or_async_event_delegate_address(
    839     Isolate* isolate) {
    840   return ExternalReference(
    841       isolate->promise_hook_or_async_event_delegate_address());
    842 }
    843 
    844 ExternalReference ExternalReference::debug_is_active_address(Isolate* isolate) {
    845   return ExternalReference(isolate->debug()->is_active_address());
    846 }
    847 
    848 ExternalReference ExternalReference::debug_hook_on_function_call_address(
    849     Isolate* isolate) {
    850   return ExternalReference(isolate->debug()->hook_on_function_call_address());
    851 }
    852 
    853 ExternalReference ExternalReference::runtime_function_table_address(
    854     Isolate* isolate) {
    855   return ExternalReference(
    856       const_cast<Runtime::Function*>(Runtime::RuntimeFunctionTable(isolate)));
    857 }
    858 
    859 ExternalReference ExternalReference::invalidate_prototype_chains_function() {
    860   return ExternalReference(
    861       Redirect(FUNCTION_ADDR(JSObject::InvalidatePrototypeChains)));
    862 }
    863 
    864 double power_helper(Isolate* isolate, double x, double y) {
    865   int y_int = static_cast<int>(y);
    866   if (y == y_int) {
    867     return power_double_int(x, y_int);  // Returns 1 if exponent is 0.
    868   }
    869   if (y == 0.5) {
    870     lazily_initialize_fast_sqrt(isolate);
    871     return (std::isinf(x)) ? V8_INFINITY
    872                            : fast_sqrt(x + 0.0, isolate);  // Convert -0 to +0.
    873   }
    874   if (y == -0.5) {
    875     lazily_initialize_fast_sqrt(isolate);
    876     return (std::isinf(x)) ? 0
    877                            : 1.0 / fast_sqrt(x + 0.0,
    878                                              isolate);  // Convert -0 to +0.
    879   }
    880   return power_double_double(x, y);
    881 }
    882 
    883 // Helper function to compute x^y, where y is known to be an
    884 // integer. Uses binary decomposition to limit the number of
    885 // multiplications; see the discussion in "Hacker's Delight" by Henry
    886 // S. Warren, Jr., figure 11-6, page 213.
    887 double power_double_int(double x, int y) {
    888   double m = (y < 0) ? 1 / x : x;
    889   unsigned n = (y < 0) ? -y : y;
    890   double p = 1;
    891   while (n != 0) {
    892     if ((n & 1) != 0) p *= m;
    893     m *= m;
    894     if ((n & 2) != 0) p *= m;
    895     m *= m;
    896     n >>= 2;
    897   }
    898   return p;
    899 }
    900 
    901 double power_double_double(double x, double y) {
    902   // The checks for special cases can be dropped in ia32 because it has already
    903   // been done in generated code before bailing out here.
    904   if (std::isnan(y) || ((x == 1 || x == -1) && std::isinf(y))) {
    905     return std::numeric_limits<double>::quiet_NaN();
    906   }
    907   return Pow(x, y);
    908 }
    909 
    910 double modulo_double_double(double x, double y) { return Modulo(x, y); }
    911 
    912 ExternalReference ExternalReference::power_double_double_function() {
    913   return ExternalReference(
    914       Redirect(FUNCTION_ADDR(power_double_double), BUILTIN_FP_FP_CALL));
    915 }
    916 
    917 ExternalReference ExternalReference::mod_two_doubles_operation() {
    918   return ExternalReference(
    919       Redirect(FUNCTION_ADDR(modulo_double_double), BUILTIN_FP_FP_CALL));
    920 }
    921 
    922 ExternalReference ExternalReference::debug_suspended_generator_address(
    923     Isolate* isolate) {
    924   return ExternalReference(isolate->debug()->suspended_generator_address());
    925 }
    926 
    927 ExternalReference ExternalReference::debug_restart_fp_address(
    928     Isolate* isolate) {
    929   return ExternalReference(isolate->debug()->restart_fp_address());
    930 }
    931 
    932 ExternalReference ExternalReference::wasm_thread_in_wasm_flag_address_address(
    933     Isolate* isolate) {
    934   return ExternalReference(reinterpret_cast<Address>(
    935       &isolate->thread_local_top()->thread_in_wasm_flag_address_));
    936 }
    937 
    938 ExternalReference ExternalReference::fixed_typed_array_base_data_offset() {
    939   return ExternalReference(reinterpret_cast<void*>(
    940       FixedTypedArrayBase::kDataOffset - kHeapObjectTag));
    941 }
    942 
    943 bool operator==(ExternalReference lhs, ExternalReference rhs) {
    944   return lhs.address() == rhs.address();
    945 }
    946 
    947 bool operator!=(ExternalReference lhs, ExternalReference rhs) {
    948   return !(lhs == rhs);
    949 }
    950 
    951 size_t hash_value(ExternalReference reference) {
    952   return base::hash<Address>()(reference.address());
    953 }
    954 
    955 std::ostream& operator<<(std::ostream& os, ExternalReference reference) {
    956   os << reinterpret_cast<const void*>(reference.address());
    957   const Runtime::Function* fn = Runtime::FunctionForEntry(reference.address());
    958   if (fn) os << "<" << fn->name << ".entry>";
    959   return os;
    960 }
    961 
    962 void abort_with_reason(int reason) {
    963   if (IsValidAbortReason(reason)) {
    964     const char* message = GetAbortReason(static_cast<AbortReason>(reason));
    965     base::OS::PrintError("abort: %s\n", message);
    966   } else {
    967     base::OS::PrintError("abort: <unknown reason: %d>\n", reason);
    968   }
    969   base::OS::Abort();
    970   UNREACHABLE();
    971 }
    972 
    973 }  // namespace internal
    974 }  // namespace v8
    975