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