• 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/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 
BuiltinCallTypeForResultSize(int result_size)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
Create(ApiFunction * fun,Type type=ExternalReference::BUILTIN_CALL)103 ExternalReference ExternalReference::Create(
104     ApiFunction* fun, Type type = ExternalReference::BUILTIN_CALL) {
105   return ExternalReference(Redirect(fun->address(), type));
106 }
107 
108 // static
Create(Runtime::FunctionId id)109 ExternalReference ExternalReference::Create(Runtime::FunctionId id) {
110   return Create(Runtime::FunctionForId(id));
111 }
112 
113 // static
Create(const Runtime::Function * f)114 ExternalReference ExternalReference::Create(const Runtime::Function* f) {
115   return ExternalReference(
116       Redirect(f->entry, BuiltinCallTypeForResultSize(f->result_size)));
117 }
118 
119 // static
Create(Address address)120 ExternalReference ExternalReference::Create(Address address) {
121   return ExternalReference(Redirect(address));
122 }
123 
isolate_address(Isolate * isolate)124 ExternalReference ExternalReference::isolate_address(Isolate* isolate) {
125   return ExternalReference(isolate);
126 }
127 
builtins_address(Isolate * isolate)128 ExternalReference ExternalReference::builtins_address(Isolate* isolate) {
129   return ExternalReference(isolate->heap()->builtin_address(0));
130 }
131 
handle_scope_implementer_address(Isolate * isolate)132 ExternalReference ExternalReference::handle_scope_implementer_address(
133     Isolate* isolate) {
134   return ExternalReference(isolate->handle_scope_implementer_address());
135 }
136 
pending_microtask_count_address(Isolate * isolate)137 ExternalReference ExternalReference::pending_microtask_count_address(
138     Isolate* isolate) {
139   return ExternalReference(isolate->pending_microtask_count_address());
140 }
141 
interpreter_dispatch_table_address(Isolate * isolate)142 ExternalReference ExternalReference::interpreter_dispatch_table_address(
143     Isolate* isolate) {
144   return ExternalReference(isolate->interpreter()->dispatch_table_address());
145 }
146 
interpreter_dispatch_counters(Isolate * isolate)147 ExternalReference ExternalReference::interpreter_dispatch_counters(
148     Isolate* isolate) {
149   return ExternalReference(
150       isolate->interpreter()->bytecode_dispatch_counters_table());
151 }
152 
bytecode_size_table_address()153 ExternalReference ExternalReference::bytecode_size_table_address() {
154   return ExternalReference(
155       interpreter::Bytecodes::bytecode_size_table_address());
156 }
157 
158 // static
Create(StatsCounter * counter)159 ExternalReference ExternalReference::Create(StatsCounter* counter) {
160   return ExternalReference(
161       reinterpret_cast<Address>(counter->GetInternalPointer()));
162 }
163 
164 // static
Create(IsolateAddressId id,Isolate * isolate)165 ExternalReference ExternalReference::Create(IsolateAddressId id,
166                                             Isolate* isolate) {
167   return ExternalReference(isolate->get_address_from_id(id));
168 }
169 
170 // static
Create(const SCTableReference & table_ref)171 ExternalReference ExternalReference::Create(const SCTableReference& table_ref) {
172   return ExternalReference(table_ref.address());
173 }
174 
175 ExternalReference
incremental_marking_record_write_function()176 ExternalReference::incremental_marking_record_write_function() {
177   return ExternalReference(
178       Redirect(FUNCTION_ADDR(IncrementalMarking::RecordWriteFromCode)));
179 }
180 
store_buffer_overflow_function()181 ExternalReference ExternalReference::store_buffer_overflow_function() {
182   return ExternalReference(
183       Redirect(Heap::store_buffer_overflow_function_address()));
184 }
185 
delete_handle_scope_extensions()186 ExternalReference ExternalReference::delete_handle_scope_extensions() {
187   return ExternalReference(
188       Redirect(FUNCTION_ADDR(HandleScope::DeleteExtensions)));
189 }
190 
get_date_field_function()191 ExternalReference ExternalReference::get_date_field_function() {
192   return ExternalReference(Redirect(FUNCTION_ADDR(JSDate::GetField)));
193 }
194 
date_cache_stamp(Isolate * isolate)195 ExternalReference ExternalReference::date_cache_stamp(Isolate* isolate) {
196   return ExternalReference(isolate->date_cache()->stamp_address());
197 }
198 
199 // static
200 ExternalReference
runtime_function_table_address_for_unittests(Isolate * isolate)201 ExternalReference::runtime_function_table_address_for_unittests(
202     Isolate* isolate) {
203   return runtime_function_table_address(isolate);
204 }
205 
206 // static
Redirect(Address address,Type type)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 
stress_deopt_count(Isolate * isolate)215 ExternalReference ExternalReference::stress_deopt_count(Isolate* isolate) {
216   return ExternalReference(isolate->stress_deopt_count_address());
217 }
218 
force_slow_path(Isolate * isolate)219 ExternalReference ExternalReference::force_slow_path(Isolate* isolate) {
220   return ExternalReference(isolate->force_slow_path_address());
221 }
222 
new_deoptimizer_function()223 ExternalReference ExternalReference::new_deoptimizer_function() {
224   return ExternalReference(Redirect(FUNCTION_ADDR(Deoptimizer::New)));
225 }
226 
compute_output_frames_function()227 ExternalReference ExternalReference::compute_output_frames_function() {
228   return ExternalReference(
229       Redirect(FUNCTION_ADDR(Deoptimizer::ComputeOutputFrames)));
230 }
231 
wasm_f32_trunc()232 ExternalReference ExternalReference::wasm_f32_trunc() {
233   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f32_trunc_wrapper)));
234 }
wasm_f32_floor()235 ExternalReference ExternalReference::wasm_f32_floor() {
236   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f32_floor_wrapper)));
237 }
wasm_f32_ceil()238 ExternalReference ExternalReference::wasm_f32_ceil() {
239   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f32_ceil_wrapper)));
240 }
wasm_f32_nearest_int()241 ExternalReference ExternalReference::wasm_f32_nearest_int() {
242   return ExternalReference(
243       Redirect(FUNCTION_ADDR(wasm::f32_nearest_int_wrapper)));
244 }
245 
wasm_f64_trunc()246 ExternalReference ExternalReference::wasm_f64_trunc() {
247   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f64_trunc_wrapper)));
248 }
249 
wasm_f64_floor()250 ExternalReference ExternalReference::wasm_f64_floor() {
251   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f64_floor_wrapper)));
252 }
253 
wasm_f64_ceil()254 ExternalReference ExternalReference::wasm_f64_ceil() {
255   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f64_ceil_wrapper)));
256 }
257 
wasm_f64_nearest_int()258 ExternalReference ExternalReference::wasm_f64_nearest_int() {
259   return ExternalReference(
260       Redirect(FUNCTION_ADDR(wasm::f64_nearest_int_wrapper)));
261 }
262 
wasm_int64_to_float32()263 ExternalReference ExternalReference::wasm_int64_to_float32() {
264   return ExternalReference(
265       Redirect(FUNCTION_ADDR(wasm::int64_to_float32_wrapper)));
266 }
267 
wasm_uint64_to_float32()268 ExternalReference ExternalReference::wasm_uint64_to_float32() {
269   return ExternalReference(
270       Redirect(FUNCTION_ADDR(wasm::uint64_to_float32_wrapper)));
271 }
272 
wasm_int64_to_float64()273 ExternalReference ExternalReference::wasm_int64_to_float64() {
274   return ExternalReference(
275       Redirect(FUNCTION_ADDR(wasm::int64_to_float64_wrapper)));
276 }
277 
wasm_uint64_to_float64()278 ExternalReference ExternalReference::wasm_uint64_to_float64() {
279   return ExternalReference(
280       Redirect(FUNCTION_ADDR(wasm::uint64_to_float64_wrapper)));
281 }
282 
wasm_float32_to_int64()283 ExternalReference ExternalReference::wasm_float32_to_int64() {
284   return ExternalReference(
285       Redirect(FUNCTION_ADDR(wasm::float32_to_int64_wrapper)));
286 }
287 
wasm_float32_to_uint64()288 ExternalReference ExternalReference::wasm_float32_to_uint64() {
289   return ExternalReference(
290       Redirect(FUNCTION_ADDR(wasm::float32_to_uint64_wrapper)));
291 }
292 
wasm_float64_to_int64()293 ExternalReference ExternalReference::wasm_float64_to_int64() {
294   return ExternalReference(
295       Redirect(FUNCTION_ADDR(wasm::float64_to_int64_wrapper)));
296 }
297 
wasm_float64_to_uint64()298 ExternalReference ExternalReference::wasm_float64_to_uint64() {
299   return ExternalReference(
300       Redirect(FUNCTION_ADDR(wasm::float64_to_uint64_wrapper)));
301 }
302 
wasm_int64_div()303 ExternalReference ExternalReference::wasm_int64_div() {
304   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::int64_div_wrapper)));
305 }
306 
wasm_int64_mod()307 ExternalReference ExternalReference::wasm_int64_mod() {
308   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::int64_mod_wrapper)));
309 }
310 
wasm_uint64_div()311 ExternalReference ExternalReference::wasm_uint64_div() {
312   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::uint64_div_wrapper)));
313 }
314 
wasm_uint64_mod()315 ExternalReference ExternalReference::wasm_uint64_mod() {
316   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::uint64_mod_wrapper)));
317 }
318 
wasm_word32_ctz()319 ExternalReference ExternalReference::wasm_word32_ctz() {
320   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word32_ctz_wrapper)));
321 }
322 
wasm_word64_ctz()323 ExternalReference ExternalReference::wasm_word64_ctz() {
324   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word64_ctz_wrapper)));
325 }
326 
wasm_word32_popcnt()327 ExternalReference ExternalReference::wasm_word32_popcnt() {
328   return ExternalReference(
329       Redirect(FUNCTION_ADDR(wasm::word32_popcnt_wrapper)));
330 }
331 
wasm_word64_popcnt()332 ExternalReference ExternalReference::wasm_word64_popcnt() {
333   return ExternalReference(
334       Redirect(FUNCTION_ADDR(wasm::word64_popcnt_wrapper)));
335 }
336 
wasm_word32_rol()337 ExternalReference ExternalReference::wasm_word32_rol() {
338   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word32_rol_wrapper)));
339 }
340 
wasm_word32_ror()341 ExternalReference ExternalReference::wasm_word32_ror() {
342   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word32_ror_wrapper)));
343 }
344 
f64_acos_wrapper(Address data)345 static void f64_acos_wrapper(Address data) {
346   double input = ReadUnalignedValue<double>(data);
347   WriteUnalignedValue(data, base::ieee754::acos(input));
348 }
349 
f64_acos_wrapper_function()350 ExternalReference ExternalReference::f64_acos_wrapper_function() {
351   return ExternalReference(Redirect(FUNCTION_ADDR(f64_acos_wrapper)));
352 }
353 
f64_asin_wrapper(Address data)354 static void f64_asin_wrapper(Address data) {
355   double input = ReadUnalignedValue<double>(data);
356   WriteUnalignedValue<double>(data, base::ieee754::asin(input));
357 }
358 
f64_asin_wrapper_function()359 ExternalReference ExternalReference::f64_asin_wrapper_function() {
360   return ExternalReference(Redirect(FUNCTION_ADDR(f64_asin_wrapper)));
361 }
362 
wasm_float64_pow()363 ExternalReference ExternalReference::wasm_float64_pow() {
364   return ExternalReference(Redirect(FUNCTION_ADDR(wasm::float64_pow_wrapper)));
365 }
366 
f64_mod_wrapper(Address data)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 
f64_mod_wrapper_function()373 ExternalReference ExternalReference::f64_mod_wrapper_function() {
374   return ExternalReference(Redirect(FUNCTION_ADDR(f64_mod_wrapper)));
375 }
376 
wasm_call_trap_callback_for_testing()377 ExternalReference ExternalReference::wasm_call_trap_callback_for_testing() {
378   return ExternalReference(
379       Redirect(FUNCTION_ADDR(wasm::call_trap_callback_for_testing)));
380 }
381 
log_enter_external_function()382 ExternalReference ExternalReference::log_enter_external_function() {
383   return ExternalReference(Redirect(FUNCTION_ADDR(Logger::EnterExternal)));
384 }
385 
log_leave_external_function()386 ExternalReference ExternalReference::log_leave_external_function() {
387   return ExternalReference(Redirect(FUNCTION_ADDR(Logger::LeaveExternal)));
388 }
389 
roots_array_start(Isolate * isolate)390 ExternalReference ExternalReference::roots_array_start(Isolate* isolate) {
391   return ExternalReference(isolate->heap()->roots_array_start());
392 }
393 
allocation_sites_list_address(Isolate * isolate)394 ExternalReference ExternalReference::allocation_sites_list_address(
395     Isolate* isolate) {
396   return ExternalReference(isolate->heap()->allocation_sites_list_address());
397 }
398 
address_of_stack_limit(Isolate * isolate)399 ExternalReference ExternalReference::address_of_stack_limit(Isolate* isolate) {
400   return ExternalReference(isolate->stack_guard()->address_of_jslimit());
401 }
402 
address_of_real_stack_limit(Isolate * isolate)403 ExternalReference ExternalReference::address_of_real_stack_limit(
404     Isolate* isolate) {
405   return ExternalReference(isolate->stack_guard()->address_of_real_jslimit());
406 }
407 
store_buffer_top(Isolate * isolate)408 ExternalReference ExternalReference::store_buffer_top(Isolate* isolate) {
409   return ExternalReference(isolate->heap()->store_buffer_top_address());
410 }
411 
heap_is_marking_flag_address(Isolate * isolate)412 ExternalReference ExternalReference::heap_is_marking_flag_address(
413     Isolate* isolate) {
414   return ExternalReference(isolate->heap()->IsMarkingFlagAddress());
415 }
416 
new_space_allocation_top_address(Isolate * isolate)417 ExternalReference ExternalReference::new_space_allocation_top_address(
418     Isolate* isolate) {
419   return ExternalReference(isolate->heap()->NewSpaceAllocationTopAddress());
420 }
421 
new_space_allocation_limit_address(Isolate * isolate)422 ExternalReference ExternalReference::new_space_allocation_limit_address(
423     Isolate* isolate) {
424   return ExternalReference(isolate->heap()->NewSpaceAllocationLimitAddress());
425 }
426 
old_space_allocation_top_address(Isolate * isolate)427 ExternalReference ExternalReference::old_space_allocation_top_address(
428     Isolate* isolate) {
429   return ExternalReference(isolate->heap()->OldSpaceAllocationTopAddress());
430 }
431 
old_space_allocation_limit_address(Isolate * isolate)432 ExternalReference ExternalReference::old_space_allocation_limit_address(
433     Isolate* isolate) {
434   return ExternalReference(isolate->heap()->OldSpaceAllocationLimitAddress());
435 }
436 
handle_scope_level_address(Isolate * isolate)437 ExternalReference ExternalReference::handle_scope_level_address(
438     Isolate* isolate) {
439   return ExternalReference(HandleScope::current_level_address(isolate));
440 }
441 
handle_scope_next_address(Isolate * isolate)442 ExternalReference ExternalReference::handle_scope_next_address(
443     Isolate* isolate) {
444   return ExternalReference(HandleScope::current_next_address(isolate));
445 }
446 
handle_scope_limit_address(Isolate * isolate)447 ExternalReference ExternalReference::handle_scope_limit_address(
448     Isolate* isolate) {
449   return ExternalReference(HandleScope::current_limit_address(isolate));
450 }
451 
scheduled_exception_address(Isolate * isolate)452 ExternalReference ExternalReference::scheduled_exception_address(
453     Isolate* isolate) {
454   return ExternalReference(isolate->scheduled_exception_address());
455 }
456 
address_of_pending_message_obj(Isolate * isolate)457 ExternalReference ExternalReference::address_of_pending_message_obj(
458     Isolate* isolate) {
459   return ExternalReference(isolate->pending_message_obj_address());
460 }
461 
abort_with_reason()462 ExternalReference ExternalReference::abort_with_reason() {
463   return ExternalReference(Redirect(FUNCTION_ADDR(i::abort_with_reason)));
464 }
465 
address_of_min_int()466 ExternalReference ExternalReference::address_of_min_int() {
467   return ExternalReference(reinterpret_cast<Address>(&double_min_int_constant));
468 }
469 
address_of_runtime_stats_flag()470 ExternalReference ExternalReference::address_of_runtime_stats_flag() {
471   return ExternalReference(&FLAG_runtime_stats);
472 }
473 
address_of_one_half()474 ExternalReference ExternalReference::address_of_one_half() {
475   return ExternalReference(
476       reinterpret_cast<Address>(&double_one_half_constant));
477 }
478 
address_of_the_hole_nan()479 ExternalReference ExternalReference::address_of_the_hole_nan() {
480   return ExternalReference(
481       reinterpret_cast<Address>(&double_the_hole_nan_constant));
482 }
483 
address_of_uint32_bias()484 ExternalReference ExternalReference::address_of_uint32_bias() {
485   return ExternalReference(
486       reinterpret_cast<Address>(&double_uint32_bias_constant));
487 }
488 
address_of_float_abs_constant()489 ExternalReference ExternalReference::address_of_float_abs_constant() {
490   return ExternalReference(reinterpret_cast<Address>(&float_absolute_constant));
491 }
492 
address_of_float_neg_constant()493 ExternalReference ExternalReference::address_of_float_neg_constant() {
494   return ExternalReference(reinterpret_cast<Address>(&float_negate_constant));
495 }
496 
address_of_double_abs_constant()497 ExternalReference ExternalReference::address_of_double_abs_constant() {
498   return ExternalReference(
499       reinterpret_cast<Address>(&double_absolute_constant));
500 }
501 
address_of_double_neg_constant()502 ExternalReference ExternalReference::address_of_double_neg_constant() {
503   return ExternalReference(reinterpret_cast<Address>(&double_negate_constant));
504 }
505 
is_profiling_address(Isolate * isolate)506 ExternalReference ExternalReference::is_profiling_address(Isolate* isolate) {
507   return ExternalReference(isolate->is_profiling_address());
508 }
509 
invoke_function_callback()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 
invoke_accessor_getter_callback()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 
re_check_stack_guard_state(Isolate * isolate)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 
re_grow_stack(Isolate * isolate)551 ExternalReference ExternalReference::re_grow_stack(Isolate* isolate) {
552   return ExternalReference(
553       Redirect(FUNCTION_ADDR(NativeRegExpMacroAssembler::GrowStack)));
554 }
555 
re_case_insensitive_compare_uc16(Isolate * isolate)556 ExternalReference ExternalReference::re_case_insensitive_compare_uc16(
557     Isolate* isolate) {
558   return ExternalReference(Redirect(
559       FUNCTION_ADDR(NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16)));
560 }
561 
re_word_character_map(Isolate * isolate)562 ExternalReference ExternalReference::re_word_character_map(Isolate* isolate) {
563   return ExternalReference(
564       NativeRegExpMacroAssembler::word_character_map_address());
565 }
566 
address_of_static_offsets_vector(Isolate * isolate)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 
address_of_regexp_stack_limit(Isolate * isolate)573 ExternalReference ExternalReference::address_of_regexp_stack_limit(
574     Isolate* isolate) {
575   return ExternalReference(isolate->regexp_stack()->limit_address());
576 }
577 
address_of_regexp_stack_memory_address(Isolate * isolate)578 ExternalReference ExternalReference::address_of_regexp_stack_memory_address(
579     Isolate* isolate) {
580   return ExternalReference(isolate->regexp_stack()->memory_address());
581 }
582 
address_of_regexp_stack_memory_size(Isolate * isolate)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 
ieee754_acos_function()590 ExternalReference ExternalReference::ieee754_acos_function() {
591   return ExternalReference(
592       Redirect(FUNCTION_ADDR(base::ieee754::acos), BUILTIN_FP_CALL));
593 }
594 
ieee754_acosh_function()595 ExternalReference ExternalReference::ieee754_acosh_function() {
596   return ExternalReference(
597       Redirect(FUNCTION_ADDR(base::ieee754::acosh), BUILTIN_FP_FP_CALL));
598 }
599 
ieee754_asin_function()600 ExternalReference ExternalReference::ieee754_asin_function() {
601   return ExternalReference(
602       Redirect(FUNCTION_ADDR(base::ieee754::asin), BUILTIN_FP_CALL));
603 }
604 
ieee754_asinh_function()605 ExternalReference ExternalReference::ieee754_asinh_function() {
606   return ExternalReference(
607       Redirect(FUNCTION_ADDR(base::ieee754::asinh), BUILTIN_FP_FP_CALL));
608 }
609 
ieee754_atan_function()610 ExternalReference ExternalReference::ieee754_atan_function() {
611   return ExternalReference(
612       Redirect(FUNCTION_ADDR(base::ieee754::atan), BUILTIN_FP_CALL));
613 }
614 
ieee754_atanh_function()615 ExternalReference ExternalReference::ieee754_atanh_function() {
616   return ExternalReference(
617       Redirect(FUNCTION_ADDR(base::ieee754::atanh), BUILTIN_FP_FP_CALL));
618 }
619 
ieee754_atan2_function()620 ExternalReference ExternalReference::ieee754_atan2_function() {
621   return ExternalReference(
622       Redirect(FUNCTION_ADDR(base::ieee754::atan2), BUILTIN_FP_FP_CALL));
623 }
624 
ieee754_cbrt_function()625 ExternalReference ExternalReference::ieee754_cbrt_function() {
626   return ExternalReference(
627       Redirect(FUNCTION_ADDR(base::ieee754::cbrt), BUILTIN_FP_FP_CALL));
628 }
629 
ieee754_cos_function()630 ExternalReference ExternalReference::ieee754_cos_function() {
631   return ExternalReference(
632       Redirect(FUNCTION_ADDR(base::ieee754::cos), BUILTIN_FP_CALL));
633 }
634 
ieee754_cosh_function()635 ExternalReference ExternalReference::ieee754_cosh_function() {
636   return ExternalReference(
637       Redirect(FUNCTION_ADDR(base::ieee754::cosh), BUILTIN_FP_CALL));
638 }
639 
ieee754_exp_function()640 ExternalReference ExternalReference::ieee754_exp_function() {
641   return ExternalReference(
642       Redirect(FUNCTION_ADDR(base::ieee754::exp), BUILTIN_FP_CALL));
643 }
644 
ieee754_expm1_function()645 ExternalReference ExternalReference::ieee754_expm1_function() {
646   return ExternalReference(
647       Redirect(FUNCTION_ADDR(base::ieee754::expm1), BUILTIN_FP_FP_CALL));
648 }
649 
ieee754_log_function()650 ExternalReference ExternalReference::ieee754_log_function() {
651   return ExternalReference(
652       Redirect(FUNCTION_ADDR(base::ieee754::log), BUILTIN_FP_CALL));
653 }
654 
ieee754_log1p_function()655 ExternalReference ExternalReference::ieee754_log1p_function() {
656   return ExternalReference(
657       Redirect(FUNCTION_ADDR(base::ieee754::log1p), BUILTIN_FP_CALL));
658 }
659 
ieee754_log10_function()660 ExternalReference ExternalReference::ieee754_log10_function() {
661   return ExternalReference(
662       Redirect(FUNCTION_ADDR(base::ieee754::log10), BUILTIN_FP_CALL));
663 }
664 
ieee754_log2_function()665 ExternalReference ExternalReference::ieee754_log2_function() {
666   return ExternalReference(
667       Redirect(FUNCTION_ADDR(base::ieee754::log2), BUILTIN_FP_CALL));
668 }
669 
ieee754_sin_function()670 ExternalReference ExternalReference::ieee754_sin_function() {
671   return ExternalReference(
672       Redirect(FUNCTION_ADDR(base::ieee754::sin), BUILTIN_FP_CALL));
673 }
674 
ieee754_sinh_function()675 ExternalReference ExternalReference::ieee754_sinh_function() {
676   return ExternalReference(
677       Redirect(FUNCTION_ADDR(base::ieee754::sinh), BUILTIN_FP_CALL));
678 }
679 
ieee754_tan_function()680 ExternalReference ExternalReference::ieee754_tan_function() {
681   return ExternalReference(
682       Redirect(FUNCTION_ADDR(base::ieee754::tan), BUILTIN_FP_CALL));
683 }
684 
ieee754_tanh_function()685 ExternalReference ExternalReference::ieee754_tanh_function() {
686   return ExternalReference(
687       Redirect(FUNCTION_ADDR(base::ieee754::tanh), BUILTIN_FP_CALL));
688 }
689 
libc_memchr(void * string,int character,size_t search_length)690 void* libc_memchr(void* string, int character, size_t search_length) {
691   return memchr(string, character, search_length);
692 }
693 
libc_memchr_function()694 ExternalReference ExternalReference::libc_memchr_function() {
695   return ExternalReference(Redirect(FUNCTION_ADDR(libc_memchr)));
696 }
697 
libc_memcpy(void * dest,const void * src,size_t n)698 void* libc_memcpy(void* dest, const void* src, size_t n) {
699   return memcpy(dest, src, n);
700 }
701 
libc_memcpy_function()702 ExternalReference ExternalReference::libc_memcpy_function() {
703   return ExternalReference(Redirect(FUNCTION_ADDR(libc_memcpy)));
704 }
705 
libc_memmove(void * dest,const void * src,size_t n)706 void* libc_memmove(void* dest, const void* src, size_t n) {
707   return memmove(dest, src, n);
708 }
709 
libc_memmove_function()710 ExternalReference ExternalReference::libc_memmove_function() {
711   return ExternalReference(Redirect(FUNCTION_ADDR(libc_memmove)));
712 }
713 
libc_memset(void * dest,int value,size_t n)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 
libc_memset_function()719 ExternalReference ExternalReference::libc_memset_function() {
720   return ExternalReference(Redirect(FUNCTION_ADDR(libc_memset)));
721 }
722 
printf_function()723 ExternalReference ExternalReference::printf_function() {
724   return ExternalReference(Redirect(FUNCTION_ADDR(std::printf)));
725 }
726 
727 template <typename SubjectChar, typename PatternChar>
search_string_raw()728 ExternalReference ExternalReference::search_string_raw() {
729   auto f = SearchStringRaw<SubjectChar, PatternChar>;
730   return ExternalReference(Redirect(FUNCTION_ADDR(f)));
731 }
732 
search_string_raw_one_one()733 ExternalReference ExternalReference::search_string_raw_one_one() {
734   return search_string_raw<const uint8_t, const uint8_t>();
735 }
736 
search_string_raw_one_two()737 ExternalReference ExternalReference::search_string_raw_one_two() {
738   return search_string_raw<const uint8_t, const uc16>();
739 }
740 
search_string_raw_two_one()741 ExternalReference ExternalReference::search_string_raw_two_one() {
742   return search_string_raw<const uc16, const uint8_t>();
743 }
744 
search_string_raw_two_two()745 ExternalReference ExternalReference::search_string_raw_two_two() {
746   return search_string_raw<const uc16, const uc16>();
747 }
748 
orderedhashmap_gethash_raw()749 ExternalReference ExternalReference::orderedhashmap_gethash_raw() {
750   auto f = OrderedHashMap::GetHash;
751   return ExternalReference(Redirect(FUNCTION_ADDR(f)));
752 }
753 
get_or_create_hash_raw(Isolate * isolate)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 
jsreceiver_create_identity_hash(Isolate * isolate)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
copy_fast_number_jsarray_elements_to_typed_array()768 ExternalReference::copy_fast_number_jsarray_elements_to_typed_array() {
769   return ExternalReference(
770       Redirect(FUNCTION_ADDR(CopyFastNumberJSArrayElementsToTypedArray)));
771 }
772 
773 ExternalReference
copy_typed_array_elements_to_typed_array()774 ExternalReference::copy_typed_array_elements_to_typed_array() {
775   return ExternalReference(
776       Redirect(FUNCTION_ADDR(CopyTypedArrayElementsToTypedArray)));
777 }
778 
copy_typed_array_elements_slice()779 ExternalReference ExternalReference::copy_typed_array_elements_slice() {
780   return ExternalReference(
781       Redirect(FUNCTION_ADDR(CopyTypedArrayElementsSlice)));
782 }
783 
try_internalize_string_function()784 ExternalReference ExternalReference::try_internalize_string_function() {
785   return ExternalReference(
786       Redirect(FUNCTION_ADDR(StringTable::LookupStringIfExists_NoAllocate)));
787 }
788 
check_object_type()789 ExternalReference ExternalReference::check_object_type() {
790   return ExternalReference(Redirect(FUNCTION_ADDR(CheckObjectType)));
791 }
792 
793 #ifdef V8_INTL_SUPPORT
intl_convert_one_byte_to_lower()794 ExternalReference ExternalReference::intl_convert_one_byte_to_lower() {
795   return ExternalReference(Redirect(FUNCTION_ADDR(ConvertOneByteToLower)));
796 }
797 
intl_to_latin1_lower_table()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 
page_flags(Page * page)814 ExternalReference ExternalReference::page_flags(Page* page) {
815   return ExternalReference(reinterpret_cast<Address>(page) +
816                            MemoryChunk::kFlagsOffset);
817 }
818 
ForDeoptEntry(Address entry)819 ExternalReference ExternalReference::ForDeoptEntry(Address entry) {
820   return ExternalReference(entry);
821 }
822 
cpu_features()823 ExternalReference ExternalReference::cpu_features() {
824   DCHECK(CpuFeatures::initialized_);
825   return ExternalReference(&CpuFeatures::supported_);
826 }
827 
promise_hook_address(Isolate * isolate)828 ExternalReference ExternalReference::promise_hook_address(Isolate* isolate) {
829   return ExternalReference(isolate->promise_hook_address());
830 }
831 
async_event_delegate_address(Isolate * isolate)832 ExternalReference ExternalReference::async_event_delegate_address(
833     Isolate* isolate) {
834   return ExternalReference(isolate->async_event_delegate_address());
835 }
836 
837 ExternalReference
promise_hook_or_async_event_delegate_address(Isolate * isolate)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 
debug_is_active_address(Isolate * isolate)844 ExternalReference ExternalReference::debug_is_active_address(Isolate* isolate) {
845   return ExternalReference(isolate->debug()->is_active_address());
846 }
847 
debug_hook_on_function_call_address(Isolate * isolate)848 ExternalReference ExternalReference::debug_hook_on_function_call_address(
849     Isolate* isolate) {
850   return ExternalReference(isolate->debug()->hook_on_function_call_address());
851 }
852 
runtime_function_table_address(Isolate * isolate)853 ExternalReference ExternalReference::runtime_function_table_address(
854     Isolate* isolate) {
855   return ExternalReference(
856       const_cast<Runtime::Function*>(Runtime::RuntimeFunctionTable(isolate)));
857 }
858 
invalidate_prototype_chains_function()859 ExternalReference ExternalReference::invalidate_prototype_chains_function() {
860   return ExternalReference(
861       Redirect(FUNCTION_ADDR(JSObject::InvalidatePrototypeChains)));
862 }
863 
power_helper(Isolate * isolate,double x,double y)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.
power_double_int(double x,int y)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 
power_double_double(double x,double y)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 
modulo_double_double(double x,double y)910 double modulo_double_double(double x, double y) { return Modulo(x, y); }
911 
power_double_double_function()912 ExternalReference ExternalReference::power_double_double_function() {
913   return ExternalReference(
914       Redirect(FUNCTION_ADDR(power_double_double), BUILTIN_FP_FP_CALL));
915 }
916 
mod_two_doubles_operation()917 ExternalReference ExternalReference::mod_two_doubles_operation() {
918   return ExternalReference(
919       Redirect(FUNCTION_ADDR(modulo_double_double), BUILTIN_FP_FP_CALL));
920 }
921 
debug_suspended_generator_address(Isolate * isolate)922 ExternalReference ExternalReference::debug_suspended_generator_address(
923     Isolate* isolate) {
924   return ExternalReference(isolate->debug()->suspended_generator_address());
925 }
926 
debug_restart_fp_address(Isolate * isolate)927 ExternalReference ExternalReference::debug_restart_fp_address(
928     Isolate* isolate) {
929   return ExternalReference(isolate->debug()->restart_fp_address());
930 }
931 
wasm_thread_in_wasm_flag_address_address(Isolate * isolate)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 
fixed_typed_array_base_data_offset()938 ExternalReference ExternalReference::fixed_typed_array_base_data_offset() {
939   return ExternalReference(reinterpret_cast<void*>(
940       FixedTypedArrayBase::kDataOffset - kHeapObjectTag));
941 }
942 
operator ==(ExternalReference lhs,ExternalReference rhs)943 bool operator==(ExternalReference lhs, ExternalReference rhs) {
944   return lhs.address() == rhs.address();
945 }
946 
operator !=(ExternalReference lhs,ExternalReference rhs)947 bool operator!=(ExternalReference lhs, ExternalReference rhs) {
948   return !(lhs == rhs);
949 }
950 
hash_value(ExternalReference reference)951 size_t hash_value(ExternalReference reference) {
952   return base::hash<Address>()(reference.address());
953 }
954 
operator <<(std::ostream & os,ExternalReference reference)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 
abort_with_reason(int reason)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