7 #if V8_TARGET_ARCH_IA32
24 static void InitializeArrayConstructorDescriptor(
25 Isolate* isolate, CodeStubDescriptor* descriptor,
26 int constant_stack_parameter_count) {
32 Runtime::kArrayConstructor)->
entry;
34 if (constant_stack_parameter_count == 0) {
35 descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
38 descriptor->Initialize(
eax, deopt_handler, constant_stack_parameter_count,
44 static void InitializeInternalArrayConstructorDescriptor(
45 Isolate* isolate, CodeStubDescriptor* descriptor,
46 int constant_stack_parameter_count) {
51 Runtime::kInternalArrayConstructor)->
entry;
53 if (constant_stack_parameter_count == 0) {
54 descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
57 descriptor->Initialize(
eax, deopt_handler, constant_stack_parameter_count,
63 void ArrayNoArgumentConstructorStub::InitializeDescriptor(
64 CodeStubDescriptor* descriptor) {
65 InitializeArrayConstructorDescriptor(isolate(), descriptor, 0);
69 void ArraySingleArgumentConstructorStub::InitializeDescriptor(
70 CodeStubDescriptor* descriptor) {
71 InitializeArrayConstructorDescriptor(isolate(), descriptor, 1);
75 void ArrayNArgumentsConstructorStub::InitializeDescriptor(
76 CodeStubDescriptor* descriptor) {
77 InitializeArrayConstructorDescriptor(isolate(), descriptor, -1);
81 void InternalArrayNoArgumentConstructorStub::InitializeDescriptor(
82 CodeStubDescriptor* descriptor) {
83 InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, 0);
87 void InternalArraySingleArgumentConstructorStub::InitializeDescriptor(
88 CodeStubDescriptor* descriptor) {
89 InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, 1);
93 void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
94 CodeStubDescriptor* descriptor) {
95 InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1);
99 #define __ ACCESS_MASM(masm)
103 ExternalReference miss) {
105 isolate()->counters()->code_stubs()->Increment();
107 CallInterfaceDescriptor descriptor = GetCallInterfaceDescriptor();
108 int param_count = descriptor.GetEnvironmentParameterCount();
112 DCHECK(param_count == 0 ||
113 eax.
is(descriptor.GetEnvironmentParameterRegister(param_count - 1)));
115 for (
int i = 0;
i < param_count; ++
i) {
116 __ push(descriptor.GetEnvironmentParameterRegister(
i));
118 __ CallExternalReference(miss, param_count);
137 const int argument_count = 1;
139 AllowExternalCallThatCantCauseGC scope(masm);
140 __ PrepareCallCFunction(argument_count,
ecx);
142 Immediate(ExternalReference::isolate_address(isolate())));
144 ExternalReference::store_buffer_overflow_function(isolate()),
158 class FloatingPointHelper :
public AllStatic {
169 static void LoadFloatOperand(MacroAssembler* masm, Register number);
174 static void CheckFloatOperands(MacroAssembler* masm,
182 static void LoadSSE2Operands(MacroAssembler* masm, Label* not_numbers);
187 Register input_reg = this->
source();
191 Label check_negative, process_64_bits, done, done_no_stash;
193 int double_offset =
offset();
204 Register scratch_candidates[3] = {
ebx,
edx,
edi };
205 for (
int i = 0;
i < 3;
i++) {
206 scratch1 = scratch_candidates[
i];
207 if (!final_result_reg.is(scratch1) && !input_reg.is(scratch1))
break;
212 Register result_reg = final_result_reg.
is(
ecx) ?
eax : final_result_reg;
216 Register save_reg = final_result_reg.
is(
ecx) ?
eax :
ecx;
220 bool stash_exponent_copy = !input_reg.is(
esp);
221 __ mov(scratch1, mantissa_operand);
223 CpuFeatureScope scope(masm,
SSE3);
225 __ fld_d(mantissa_operand);
227 __ mov(
ecx, exponent_operand);
228 if (stash_exponent_copy)
__ push(
ecx);
241 __ sub(
ecx, Immediate(delta));
242 __ xor_(result_reg, result_reg);
243 __ cmp(
ecx, Immediate(31));
246 __ jmp(&check_negative);
248 __ bind(&process_64_bits);
250 CpuFeatureScope scope(masm,
SSE3);
251 if (stash_exponent_copy) {
260 __ fisttp_d(Operand(
esp, 0));
261 __ mov(result_reg, Operand(
esp, 0));
263 __ jmp(&done_no_stash);
266 __ sub(
ecx, Immediate(delta));
268 if (stash_exponent_copy) {
271 __ mov(result_reg, exponent_operand);
277 __ shrd(result_reg, scratch1);
278 __ shr_cl(result_reg);
279 __ test(
ecx, Immediate(32));
284 __ bind(&check_negative);
285 __ mov(result_reg, scratch1);
287 if (stash_exponent_copy) {
290 __ cmp(exponent_operand, Immediate(0));
296 if (stash_exponent_copy) {
299 __ bind(&done_no_stash);
300 if (!final_result_reg.is(result_reg)) {
302 __ mov(final_result_reg, result_reg);
310 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm,
312 Label load_smi, done;
314 __ JumpIfSmi(number, &load_smi, Label::kNear);
316 __ jmp(&done, Label::kNear);
321 __ fild_s(Operand(
esp, 0));
328 void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm,
329 Label* not_numbers) {
330 Label load_smi_edx, load_eax, load_smi_eax, load_float_eax, done;
332 __ JumpIfSmi(
edx, &load_smi_edx, Label::kNear);
333 Factory* factory = masm->isolate()->factory();
339 __ JumpIfSmi(
eax, &load_smi_eax, Label::kNear);
341 __ j(
equal, &load_float_eax, Label::kNear);
343 __ bind(&load_smi_edx);
348 __ bind(&load_smi_eax);
352 __ jmp(&done, Label::kNear);
353 __ bind(&load_float_eax);
359 void FloatingPointHelper::CheckFloatOperands(MacroAssembler* masm,
362 Label test_other, done;
365 __ JumpIfSmi(
edx, &test_other, Label::kNear);
367 Factory* factory = masm->isolate()->factory();
368 __ cmp(scratch, factory->heap_number_map());
371 __ bind(&test_other);
372 __ JumpIfSmi(
eax, &done, Label::kNear);
374 __ cmp(scratch, factory->heap_number_map());
383 Factory* factory = isolate()->factory();
386 const Register base =
edx;
387 const Register scratch =
ecx;
388 const XMMRegister double_result =
xmm3;
389 const XMMRegister double_base =
xmm2;
390 const XMMRegister double_exponent =
xmm1;
391 const XMMRegister double_scratch =
xmm4;
393 Label call_runtime, done, exponent_not_smi, int_exponent;
396 __ mov(scratch, Immediate(1));
397 __ Cvtsi2sd(double_result, scratch);
400 Label base_is_smi, unpack_exponent;
407 __ JumpIfSmi(base, &base_is_smi, Label::kNear);
409 factory->heap_number_map());
413 __ jmp(&unpack_exponent, Label::kNear);
415 __ bind(&base_is_smi);
417 __ Cvtsi2sd(double_base, base);
419 __ bind(&unpack_exponent);
420 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
421 __ SmiUntag(exponent);
422 __ jmp(&int_exponent);
424 __ bind(&exponent_not_smi);
426 factory->heap_number_map());
428 __ movsd(double_exponent,
431 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
432 __ SmiUntag(exponent);
433 __ jmp(&int_exponent);
435 __ bind(&exponent_not_smi);
436 __ movsd(double_exponent,
441 Label fast_power, try_arithmetic_simplification;
442 __ DoubleToI(exponent, double_exponent, double_scratch,
444 &try_arithmetic_simplification,
445 &try_arithmetic_simplification);
446 __ jmp(&int_exponent);
448 __ bind(&try_arithmetic_simplification);
450 __ cvttsd2si(exponent, Operand(double_exponent));
451 __ cmp(exponent, Immediate(0x1));
458 Label continue_sqrt, continue_rsqrt, not_plus_half;
461 __ mov(scratch, Immediate(0x3F000000u));
462 __ movd(double_scratch, scratch);
463 __ cvtss2sd(double_scratch, double_scratch);
465 __ ucomisd(double_scratch, double_exponent);
472 __ mov(scratch, 0xFF800000u);
473 __ movd(double_scratch, scratch);
474 __ cvtss2sd(double_scratch, double_scratch);
475 __ ucomisd(double_base, double_scratch);
479 __ j(
carry, &continue_sqrt, Label::kNear);
482 __ xorps(double_result, double_result);
483 __ subsd(double_result, double_scratch);
486 __ bind(&continue_sqrt);
488 __ xorps(double_scratch, double_scratch);
489 __ addsd(double_scratch, double_base);
490 __ sqrtsd(double_result, double_scratch);
494 __ bind(¬_plus_half);
496 __ subsd(double_scratch, double_result);
498 __ ucomisd(double_scratch, double_exponent);
505 __ mov(scratch, 0xFF800000u);
506 __ movd(double_scratch, scratch);
507 __ cvtss2sd(double_scratch, double_scratch);
508 __ ucomisd(double_base, double_scratch);
512 __ j(
carry, &continue_rsqrt, Label::kNear);
515 __ xorps(double_result, double_result);
518 __ bind(&continue_rsqrt);
520 __ xorps(double_exponent, double_exponent);
521 __ addsd(double_exponent, double_base);
522 __ sqrtsd(double_exponent, double_exponent);
523 __ divsd(double_result, double_exponent);
528 Label fast_power_failed;
529 __ bind(&fast_power);
533 __ movsd(Operand(
esp, 0), double_exponent);
534 __ fld_d(Operand(
esp, 0));
535 __ movsd(Operand(
esp, 0), double_base);
536 __ fld_d(Operand(
esp, 0));
555 __ test_b(
eax, 0x5F);
556 __ j(
not_zero, &fast_power_failed, Label::kNear);
557 __ fstp_d(Operand(
esp, 0));
558 __ movsd(double_result, Operand(
esp, 0));
562 __ bind(&fast_power_failed);
565 __ jmp(&call_runtime);
569 __ bind(&int_exponent);
570 const XMMRegister double_scratch2 = double_exponent;
571 __ mov(scratch, exponent);
572 __ movsd(double_scratch, double_base);
573 __ movsd(double_scratch2, double_result);
576 Label no_neg, while_true, while_false;
577 __ test(scratch, scratch);
582 __ j(
zero, &while_false, Label::kNear);
586 __ j(
above, &while_true, Label::kNear);
587 __ movsd(double_result, double_scratch);
588 __ j(
zero, &while_false, Label::kNear);
590 __ bind(&while_true);
592 __ mulsd(double_scratch, double_scratch);
593 __ j(
above, &while_true, Label::kNear);
594 __ mulsd(double_result, double_scratch);
597 __ bind(&while_false);
600 __ test(exponent, exponent);
602 __ divsd(double_scratch2, double_result);
603 __ movsd(double_result, double_scratch2);
606 __ xorps(double_scratch2, double_scratch2);
607 __ ucomisd(double_scratch2, double_result);
612 __ Cvtsi2sd(double_exponent, exponent);
615 Counters* counters = isolate()->counters();
618 __ bind(&call_runtime);
619 __ TailCallRuntime(Runtime::kMathPowRT, 2, 1);
624 __ AllocateHeapNumber(
eax, scratch, base, &call_runtime);
626 __ IncrementCounter(counters->math_pow(), 1);
629 __ bind(&call_runtime);
631 AllowExternalCallThatCantCauseGC scope(masm);
632 __ PrepareCallCFunction(4, scratch);
636 ExternalReference::power_double_double_function(isolate()), 4);
641 __ fstp_d(Operand(
esp, 0));
642 __ movsd(double_result, Operand(
esp, 0));
646 __ IncrementCounter(counters->math_pow(), 1);
659 PropertyAccessCompiler::TailCallBuiltin(
660 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
670 Register scratch =
eax;
671 DCHECK(!scratch.is(receiver) && !scratch.is(key));
684 ExternalReference ref = ExternalReference(
685 IC_Utility(IC::kLoadElementWithInterceptor), masm->isolate());
686 __ TailCallExternalReference(ref, 2, 1);
689 PropertyAccessCompiler::TailCallBuiltin(
690 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
706 __ JumpIfNotSmi(
edx, &slow, Label::kNear);
713 __ j(
equal, &adaptor, Label::kNear);
751 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1);
776 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
793 Label adaptor_frame, try_allocate;
797 __ j(
equal, &adaptor_frame, Label::kNear);
801 __ jmp(&try_allocate, Label::kNear);
804 __ bind(&adaptor_frame);
819 __ bind(&try_allocate);
826 const int kParameterMapHeaderSize =
828 Label no_parameter_map;
830 __ j(
zero, &no_parameter_map, Label::kNear);
832 __ bind(&no_parameter_map);
849 Label has_mapped_parameters, instantiate;
854 __ j(
not_zero, &has_mapped_parameters, Label::kNear);
858 __ jmp(&instantiate, Label::kNear);
860 __ bind(&has_mapped_parameters);
864 __ bind(&instantiate);
876 masm->isolate()->factory()->empty_fixed_array());
878 masm->isolate()->factory()->empty_fixed_array());
883 __ AssertNotSmi(
edx);
912 Label skip_parameter_map;
914 __ j(
zero, &skip_parameter_map);
917 Immediate(isolate()->factory()->sloppy_arguments_elements_map()));
932 Label parameters_loop, parameters_test;
938 __ mov(
ecx, isolate()->factory()->the_hole_value());
951 __ jmp(¶meters_test, Label::kNear);
953 __ bind(¶meters_loop);
958 __ bind(¶meters_test);
960 __ j(
not_zero, ¶meters_loop, Label::kNear);
963 __ bind(&skip_parameter_map);
973 Immediate(isolate()->factory()->fixed_array_map()));
976 Label arguments_loop, arguments_test;
981 __ jmp(&arguments_test, Label::kNear);
983 __ bind(&arguments_loop);
989 __ bind(&arguments_test);
991 __ j(
less, &arguments_loop, Label::kNear);
1004 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
1015 Label adaptor_frame, try_allocate, runtime;
1019 __ j(
equal, &adaptor_frame, Label::kNear);
1023 __ jmp(&try_allocate, Label::kNear);
1026 __ bind(&adaptor_frame);
1035 Label add_arguments_object;
1036 __ bind(&try_allocate);
1038 __ j(
zero, &add_arguments_object, Label::kNear);
1040 __ bind(&add_arguments_object);
1054 masm->isolate()->factory()->empty_fixed_array());
1056 masm->isolate()->factory()->empty_fixed_array());
1069 __ j(
zero, &done, Label::kNear);
1079 Immediate(isolate()->factory()->fixed_array_map()));
1101 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1);
1109 #ifdef V8_INTERPRETED_REGEXP
1110 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1);
1120 static const int kLastMatchInfoOffset = 1 *
kPointerSize;
1121 static const int kPreviousIndexOffset = 2 *
kPointerSize;
1126 Factory* factory = isolate()->factory();
1129 ExternalReference address_of_regexp_stack_memory_address =
1130 ExternalReference::address_of_regexp_stack_memory_address(isolate());
1131 ExternalReference address_of_regexp_stack_memory_size =
1132 ExternalReference::address_of_regexp_stack_memory_size(isolate());
1133 __ mov(
ebx, Operand::StaticVariable(address_of_regexp_stack_memory_size));
1138 __ mov(
eax, Operand(
esp, kJSRegExpOffset));
1140 __ JumpIfSmi(
eax, &runtime);
1146 if (FLAG_debug_code) {
1148 __ Check(
not_zero, kUnexpectedTypeForRegExpDataFixedArrayExpected);
1150 __ Check(
equal, kUnexpectedTypeForRegExpDataFixedArrayExpected);
1172 __ Move(
edi, Immediate(0));
1173 __ mov(
eax, Operand(
esp, kSubjectOffset));
1174 __ JumpIfSmi(
eax, &runtime);
1203 Label seq_one_byte_string , seq_two_byte_string ,
1204 external_string , check_underlying ,
1205 not_seq_nor_cons , check_code ,
1214 __ j(
zero, &seq_two_byte_string);
1221 __ j(
zero, &seq_one_byte_string, Label::kNear);
1238 __ bind(&check_underlying);
1245 __ j(
zero, &seq_two_byte_string);
1257 __ bind(&seq_one_byte_string);
1261 __ mov(
ebx, Operand(
esp, kPreviousIndexOffset));
1262 __ JumpIfNotSmi(
ebx, &runtime);
1266 __ Move(
ecx, Immediate(1));
1269 __ bind(&check_code);
1274 __ JumpIfSmi(
edx, &runtime);
1281 Counters* counters = isolate()->counters();
1282 __ IncrementCounter(counters->regexp_entry_native(), 1);
1285 static const int kRegExpExecuteArguments = 9;
1286 __ EnterApiExitFrame(kRegExpExecuteArguments);
1290 Immediate(ExternalReference::isolate_address(isolate())));
1296 __ mov(
esi, Operand::StaticVariable(address_of_regexp_stack_memory_address));
1297 __ add(
esi, Operand::StaticVariable(address_of_regexp_stack_memory_size));
1306 Immediate(ExternalReference::address_of_static_offsets_vector(
1337 Label setup_two_byte, setup_rest;
1339 __ j(
zero, &setup_two_byte, Label::kNear);
1345 __ jmp(&setup_rest, Label::kNear);
1347 __ bind(&setup_two_byte);
1355 __ bind(&setup_rest);
1362 __ LeaveApiExitFrame(
true);
1380 ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
1382 __ mov(
edx, Immediate(isolate()->factory()->the_hole_value()));
1383 __ mov(
eax, Operand::StaticVariable(pending_exception));
1389 __ mov(Operand::StaticVariable(pending_exception),
edx);
1393 __ cmp(
eax, factory->termination_exception());
1394 Label throw_termination_exception;
1395 __ j(
equal, &throw_termination_exception, Label::kNear);
1400 __ bind(&throw_termination_exception);
1401 __ ThrowUncatchable(
eax);
1405 __ mov(
eax, factory->null_value());
1410 __ mov(
eax, Operand(
esp, kJSRegExpOffset));
1416 __ add(
edx, Immediate(2));
1421 __ mov(
eax, Operand(
esp, kLastMatchInfoOffset));
1422 __ JumpIfSmi(
eax, &runtime);
1428 __ cmp(
eax, factory->fixed_array_map());
1445 __ mov(
eax, Operand(
esp, kSubjectOffset));
1448 __ RecordWriteField(
ebx,
1455 __ RecordWriteField(
ebx,
1462 ExternalReference address_of_static_offsets_vector =
1463 ExternalReference::address_of_static_offsets_vector(isolate());
1464 __ mov(
ecx, Immediate(address_of_static_offsets_vector));
1469 Label next_capture, done;
1472 __ bind(&next_capture);
1473 __ sub(
edx, Immediate(1));
1484 __ jmp(&next_capture);
1488 __ mov(
eax, Operand(
esp, kLastMatchInfoOffset));
1493 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1);
1497 __ bind(¬_seq_nor_cons);
1499 __ j(
greater, ¬_long_external, Label::kNear);
1502 __ bind(&external_string);
1506 if (FLAG_debug_code) {
1510 __ Assert(
zero, kExternalStringExpectedButNotFound);
1525 __ bind(&seq_two_byte_string);
1529 __ mov(
ebx, Operand(
esp, kPreviousIndexOffset));
1530 __ JumpIfNotSmi(
ebx, &runtime);
1534 __ Move(
ecx, Immediate(0));
1535 __ jmp(&check_code);
1538 __ bind(¬_long_external);
1548 __ jmp(&check_underlying);
1553 static int NegativeComparisonResult(
Condition cc) {
1561 static void CheckInputType(MacroAssembler* masm, Register input,
1565 __ JumpIfNotSmi(input, fail);
1567 __ JumpIfSmi(input, &ok);
1569 Immediate(masm->isolate()->factory()->heap_number_map()));
1578 static void BranchIfNotInternalizedString(MacroAssembler* masm,
1582 __ JumpIfSmi(
object, label);
1592 Label check_unequal_objects;
1596 CheckInputType(masm,
edx,
left(), &miss);
1597 CheckInputType(masm,
eax,
right(), &miss);
1600 Label non_smi, smi_done;
1603 __ JumpIfNotSmi(
ecx, &non_smi, Label::kNear);
1617 Label generic_heap_number_comparison;
1619 Label not_identical;
1626 Label check_for_nan;
1627 __ cmp(
edx, isolate()->factory()->undefined_value());
1631 __ bind(&check_for_nan);
1637 Immediate(isolate()->factory()->heap_number_map()));
1638 __ j(
equal, &generic_heap_number_comparison, Label::kNear);
1648 __ bind(¬_identical);
1673 __ sub(
ecx, Immediate(0x01));
1682 Immediate(isolate()->factory()->heap_number_map()));
1684 __ j(
equal, &slow, Label::kNear);
1696 Label first_non_object;
1699 __ j(
below, &first_non_object, Label::kNear);
1702 Label return_not_equal;
1704 __ bind(&return_not_equal);
1707 __ bind(&first_non_object);
1710 __ j(
equal, &return_not_equal);
1717 __ j(
equal, &return_not_equal);
1724 Label non_number_comparison;
1726 __ bind(&generic_heap_number_comparison);
1728 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison);
1742 __ bind(&unordered);
1752 __ bind(&non_number_comparison);
1755 Label check_for_strings;
1757 BranchIfNotInternalizedString(masm, &check_for_strings,
eax,
ecx);
1758 BranchIfNotInternalizedString(masm, &check_for_strings,
edx,
ecx);
1766 __ bind(&check_for_strings);
1769 &check_unequal_objects);
1779 __ Abort(kUnexpectedFallThroughFromStringComparison);
1782 __ bind(&check_unequal_objects);
1787 Label not_both_objects;
1788 Label return_unequal;
1796 __ j(
not_zero, ¬_both_objects, Label::kNear);
1798 __ j(
below, ¬_both_objects, Label::kNear);
1800 __ j(
below, ¬_both_objects, Label::kNear);
1806 __ j(
zero, &return_unequal, Label::kNear);
1809 __ j(
zero, &return_unequal, Label::kNear);
1813 __ bind(&return_unequal);
1817 __ bind(¬_both_objects);
1828 builtin =
strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
1830 builtin = Builtins::COMPARE;
1846 static void GenerateRecordCallTarget(MacroAssembler* masm) {
1854 Isolate* isolate = masm->isolate();
1855 Label initialize, done, miss, megamorphic, not_array_function;
1864 __ j(
equal, &done, Label::kFar);
1866 __ j(
equal, &done, Label::kFar);
1868 if (!FLAG_pretenuring_call_new) {
1873 Handle<Map> allocation_site_map = isolate->factory()->allocation_site_map();
1881 __ jmp(&done, Label::kFar);
1892 __ bind(&megamorphic);
1896 __ jmp(&done, Label::kFar);
1900 __ bind(&initialize);
1901 if (!FLAG_pretenuring_call_new) {
1920 CreateAllocationSiteStub create_stub(isolate);
1921 __ CallStub(&create_stub);
1931 __ bind(¬_array_function);
1951 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
1965 static void EmitSlowCase(Isolate* isolate,
1966 MacroAssembler* masm,
1968 Label* non_function) {
1975 __ Move(
eax, Immediate(argc + 1));
1976 __ Move(
ebx, Immediate(0));
1977 __ GetBuiltinEntry(
edx, Builtins::CALL_FUNCTION_PROXY);
1979 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
1985 __ bind(non_function);
1987 __ Move(
eax, Immediate(argc));
1988 __ Move(
ebx, Immediate(0));
1989 __ GetBuiltinEntry(
edx, Builtins::CALL_NON_FUNCTION);
1990 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
1995 static void EmitWrapCase(MacroAssembler* masm,
int argc, Label* cont) {
2008 static void CallFunctionNoFeedback(MacroAssembler* masm,
2009 int argc,
bool needs_checks,
2010 bool call_as_method) {
2012 Label slow, non_function, wrap, cont;
2016 __ JumpIfSmi(
edi, &non_function);
2024 ParameterCount actual(argc);
2026 if (call_as_method) {
2028 EmitContinueIfStrictOrNative(masm, &cont);
2035 __ JumpIfSmi(
eax, &wrap);
2052 EmitSlowCase(masm->isolate(), masm, argc, &non_function);
2055 if (call_as_method) {
2057 EmitWrapCase(masm, argc, &cont);
2073 Label slow, non_function_call;
2076 __ JumpIfSmi(
edi, &non_function_call);
2082 GenerateRecordCallTarget(masm);
2084 if (FLAG_pretenuring_call_new) {
2091 Label feedback_register_initialized;
2095 Handle<Map> allocation_site_map =
2096 isolate()->factory()->allocation_site_map();
2098 __ j(
equal, &feedback_register_initialized);
2099 __ mov(
ebx, isolate()->factory()->undefined_value());
2100 __ bind(&feedback_register_initialized);
2103 __ AssertUndefinedOrAllocationSite(
ebx);
2107 Register jmp_reg =
ecx;
2121 __ GetBuiltinEntry(
edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
2124 __ bind(&non_function_call);
2125 __ GetBuiltinEntry(
edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
2128 __ Move(
ebx, Immediate(0));
2129 Handle<Code> arguments_adaptor =
2130 isolate()->builtins()->ArgumentsAdaptorTrampoline();
2135 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
2148 ParameterCount actual(argc);
2150 EmitLoadTypeFeedbackVector(masm,
ebx);
2161 Factory* factory = masm->isolate()->factory();
2163 factory->allocation_site_map());
2167 ArrayConstructorStub stub(masm->isolate(),
arg_count());
2168 __ TailCallStub(&stub);
2174 CallFunctionNoFeedback(masm,
2187 Isolate* isolate = masm->isolate();
2188 Label extra_checks_or_miss, slow_start;
2189 Label slow, non_function, wrap, cont;
2190 Label have_js_function;
2192 ParameterCount actual(argc);
2194 EmitLoadTypeFeedbackVector(masm,
ebx);
2201 __ bind(&have_js_function);
2203 EmitContinueIfStrictOrNative(masm, &cont);
2208 __ JumpIfSmi(
eax, &wrap);
2219 EmitSlowCase(isolate, masm, argc, &non_function);
2223 EmitWrapCase(masm, argc, &cont);
2226 __ bind(&extra_checks_or_miss);
2236 if (!FLAG_trace_ic) {
2239 __ AssertNotSmi(
ecx);
2245 __ jmp(&slow_start);
2253 __ bind(&slow_start);
2256 __ JumpIfSmi(
edi, &non_function);
2261 __ jmp(&have_js_function);
2283 : IC::kCallIC_Customization_Miss;
2285 ExternalReference miss = ExternalReference(IC_Utility(
id),
2287 __ CallExternalReference(miss, 4);
2300 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
2308 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
2312 void CodeStub::GenerateFPStubs(Isolate* isolate) {
2315 isolate->set_fp_stubs_generated(
true);
2347 if (FLAG_debug_code) {
2348 __ CheckStackAlignment();
2355 Immediate(ExternalReference::isolate_address(isolate())));
2361 if (FLAG_debug_code) {
2363 __ cmp(
eax, isolate()->factory()->the_hole_value());
2370 Label exception_returned;
2371 __ cmp(
eax, isolate()->factory()->exception());
2372 __ j(
equal, &exception_returned);
2374 ExternalReference pending_exception_address(
2375 Isolate::kPendingExceptionAddress, isolate());
2379 if (FLAG_debug_code) {
2381 __ mov(
edx, Immediate(isolate()->factory()->the_hole_value()));
2383 __ cmp(
edx, Operand::StaticVariable(pending_exception_address));
2385 __ j(
equal, &okay, Label::kNear);
2396 __ bind(&exception_returned);
2399 __ mov(
eax, Operand::StaticVariable(pending_exception_address));
2402 __ mov(
edx, Immediate(isolate()->factory()->the_hole_value()));
2403 __ mov(Operand::StaticVariable(pending_exception_address),
edx);
2407 Label throw_termination_exception;
2408 __ cmp(
eax, isolate()->factory()->termination_exception());
2409 __ j(
equal, &throw_termination_exception);
2414 __ bind(&throw_termination_exception);
2415 __ ThrowUncatchable(
eax);
2420 Label invoke, handler_entry, exit;
2421 Label not_outermost_js, not_outermost_js_2;
2430 int marker =
type();
2439 ExternalReference c_entry_fp(Isolate::kCEntryFPAddress, isolate());
2440 __ push(Operand::StaticVariable(c_entry_fp));
2443 ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate());
2444 __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0));
2446 __ mov(Operand::StaticVariable(js_entry_sp),
ebp);
2447 __ push(Immediate(
Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
2448 __ jmp(&invoke, Label::kNear);
2449 __ bind(¬_outermost_js);
2450 __ push(Immediate(
Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
2455 __ bind(&handler_entry);
2459 ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
2461 __ mov(Operand::StaticVariable(pending_exception),
eax);
2462 __ mov(
eax, Immediate(isolate()->factory()->exception()));
2468 __ PushTryHandler(StackHandler::JS_ENTRY, 0);
2471 __ mov(
edx, Immediate(isolate()->factory()->the_hole_value()));
2472 __ mov(Operand::StaticVariable(pending_exception),
edx);
2475 __ push(Immediate(0));
2481 if (
type() == StackFrame::ENTRY_CONSTRUCT) {
2482 ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
2484 __ mov(
edx, Immediate(construct_entry));
2486 ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
2487 __ mov(
edx, Immediate(entry));
2501 __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0));
2502 __ bind(¬_outermost_js_2);
2505 __ pop(Operand::StaticVariable(ExternalReference(
2506 Isolate::kCEntryFPAddress, isolate())));
2541 Register
object =
eax;
2543 Register
function =
edx;
2544 Register prototype =
edi;
2545 Register scratch =
ecx;
2548 static const int kDeltaToCmpImmediate = 2;
2549 static const int kDeltaToMov = 8;
2550 static const int kDeltaToMovImmediate = 9;
2551 static const int8_t kCmpEdiOperandByte1 = bit_cast<int8_t, uint8_t>(0x3b);
2552 static const int8_t kCmpEdiOperandByte2 = bit_cast<int8_t, uint8_t>(0x3d);
2553 static const int8_t kMovEaxImmediateByte = bit_cast<int8_t, uint8_t>(0xb8);
2559 Label slow, not_js_object;
2566 __ JumpIfSmi(
object, ¬_js_object);
2567 __ IsObjectJSObjectType(
object,
map, scratch, ¬_js_object);
2574 __ CompareRoot(
function, scratch, Heap::kInstanceofCacheFunctionRootIndex);
2576 __ CompareRoot(
map, scratch, Heap::kInstanceofCacheMapRootIndex);
2578 __ LoadRoot(
eax, Heap::kInstanceofCacheAnswerRootIndex);
2584 __ TryGetFunctionPrototype(
function, prototype, scratch, &slow,
true);
2587 __ JumpIfSmi(prototype, &slow);
2588 __ IsObjectJSObjectType(prototype, scratch, scratch, &slow);
2593 __ StoreRoot(
map, scratch, Heap::kInstanceofCacheMapRootIndex);
2594 __ StoreRoot(
function, scratch, Heap::kInstanceofCacheFunctionRootIndex);
2602 if (FLAG_debug_code) {
2603 __ cmpb(Operand(scratch, 0), kCmpEdiOperandByte1);
2604 __ Assert(
equal, kInstanceofStubUnexpectedCallSiteCacheCmp1);
2605 __ cmpb(Operand(scratch, 1), kCmpEdiOperandByte2);
2606 __ Assert(
equal, kInstanceofStubUnexpectedCallSiteCacheCmp2);
2608 __ mov(scratch, Operand(scratch, kDeltaToCmpImmediate));
2609 __ mov(Operand(scratch, 0),
map);
2615 Label loop, is_instance, is_not_instance;
2617 __ cmp(scratch, prototype);
2618 __ j(
equal, &is_instance, Label::kNear);
2619 Factory* factory = isolate()->factory();
2620 __ cmp(scratch, Immediate(factory->null_value()));
2621 __ j(
equal, &is_not_instance, Label::kNear);
2626 __ bind(&is_instance);
2628 __ mov(
eax, Immediate(0));
2629 __ StoreRoot(
eax, scratch, Heap::kInstanceofCacheAnswerRootIndex);
2631 __ mov(
eax, factory->true_value());
2635 __ mov(
eax, factory->true_value());
2638 if (FLAG_debug_code) {
2639 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte);
2640 __ Assert(
equal, kInstanceofStubUnexpectedCallSiteCacheMov);
2642 __ mov(Operand(scratch, kDeltaToMovImmediate),
eax);
2644 __ Move(
eax, Immediate(0));
2649 __ bind(&is_not_instance);
2652 __ StoreRoot(
eax, scratch, Heap::kInstanceofCacheAnswerRootIndex);
2654 __ mov(
eax, factory->false_value());
2658 __ mov(
eax, factory->false_value());
2661 if (FLAG_debug_code) {
2662 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte);
2663 __ Assert(
equal, kInstanceofStubUnexpectedCallSiteCacheMov);
2665 __ mov(Operand(scratch, kDeltaToMovImmediate),
eax);
2672 Label object_not_null, object_not_null_or_smi;
2673 __ bind(¬_js_object);
2676 __ JumpIfSmi(
function, &slow, Label::kNear);
2681 __ cmp(
object, factory->null_value());
2684 __ mov(
eax, factory->false_value());
2690 __ bind(&object_not_null);
2692 __ JumpIfNotSmi(
object, &object_not_null_or_smi, Label::kNear);
2694 __ mov(
eax, factory->false_value());
2700 __ bind(&object_not_null_or_smi);
2702 Condition is_string = masm->IsObjectStringType(
object, scratch, scratch);
2705 __ mov(
eax, factory->false_value());
2731 Label true_value, done;
2733 __ j(
zero, &true_value, Label::kNear);
2734 __ mov(
eax, factory->false_value());
2735 __ jmp(&done, Label::kNear);
2736 __ bind(&true_value);
2737 __ mov(
eax, factory->true_value());
2770 Factory* factory = masm->isolate()->factory();
2780 MacroAssembler* masm,
2781 const RuntimeCallHelper& call_helper) {
2782 __ Abort(kUnexpectedFallthroughToCharCodeAtSlowCase);
2788 masm->isolate()->factory()->heap_number_map(),
2791 call_helper.BeforeCall(masm);
2795 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
2799 __ CallRuntime(Runtime::kNumberToSmi, 1);
2810 call_helper.AfterCall(masm);
2821 call_helper.BeforeCall(masm);
2825 __ CallRuntime(Runtime::kStringCharCodeAtRT, 2);
2829 call_helper.AfterCall(masm);
2832 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase);
2849 Factory* factory = masm->isolate()->factory();
2850 __ Move(
result_, Immediate(factory->single_character_string_cache()));
2858 __ cmp(
result_, factory->undefined_value());
2865 MacroAssembler* masm,
2866 const RuntimeCallHelper& call_helper) {
2867 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase);
2870 call_helper.BeforeCall(masm);
2872 __ CallRuntime(Runtime::kCharFromCode, 1);
2876 call_helper.AfterCall(masm);
2879 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase);
2889 DCHECK(!scratch.is(dest));
2890 DCHECK(!scratch.is(src));
2891 DCHECK(!scratch.is(count));
2895 __ test(count, count);
2905 __ mov_b(scratch, Operand(src, 0));
2906 __ mov_b(Operand(dest, 0), scratch);
2928 __ JumpIfSmi(
eax, &runtime);
2937 __ JumpIfNotSmi(
ecx, &runtime);
2939 __ JumpIfNotSmi(
edx, &runtime);
2942 Label not_original_string;
2944 __ j(
below, ¬_original_string, Label::kNear);
2948 Counters* counters = isolate()->counters();
2949 __ IncrementCounter(counters->sub_string_native(), 1);
2951 __ bind(¬_original_string);
2963 Label underlying_unpacked, sliced_string, seq_or_external_string;
2968 __ j(
zero, &seq_or_external_string, Label::kNear);
2970 Factory* factory = isolate()->factory();
2972 __ j(
not_zero, &sliced_string, Label::kNear);
2976 factory->empty_string());
2982 __ jmp(&underlying_unpacked, Label::kNear);
2984 __ bind(&sliced_string);
2991 __ jmp(&underlying_unpacked, Label::kNear);
2993 __ bind(&seq_or_external_string);
2997 __ bind(&underlying_unpacked);
2999 if (FLAG_string_slices) {
3007 __ j(
less, ©_routine);
3013 Label two_byte_slice, set_slice_header;
3017 __ j(
zero, &two_byte_slice, Label::kNear);
3019 __ jmp(&set_slice_header, Label::kNear);
3020 __ bind(&two_byte_slice);
3022 __ bind(&set_slice_header);
3028 __ IncrementCounter(counters->sub_string_native(), 1);
3031 __ bind(©_routine);
3040 Label two_byte_sequential, runtime_drop_two, sequential_string;
3044 __ j(
zero, &sequential_string);
3056 __ bind(&sequential_string);
3063 __ j(
zero, &two_byte_sequential);
3085 __ IncrementCounter(counters->sub_string_native(), 1);
3088 __ bind(&two_byte_sequential);
3113 __ IncrementCounter(counters->sub_string_native(), 1);
3117 __ bind(&runtime_drop_two);
3122 __ TailCallRuntime(Runtime::kSubString, 3, 1);
3124 __ bind(&single_char);
3129 StringCharAtGenerator generator(
3131 generator.GenerateFast(masm);
3133 generator.SkipSlow(masm, &runtime);
3141 Register scratch2) {
3142 Register length = scratch1;
3145 Label strings_not_equal, check_zero_length;
3148 __ j(
equal, &check_zero_length, Label::kNear);
3149 __ bind(&strings_not_equal);
3154 Label compare_chars;
3155 __ bind(&check_zero_length);
3157 __ test(length, length);
3158 __ j(
not_zero, &compare_chars, Label::kNear);
3163 __ bind(&compare_chars);
3165 &strings_not_equal, Label::kNear);
3174 MacroAssembler* masm, Register left, Register right, Register scratch1,
3175 Register scratch2, Register scratch3) {
3176 Counters* counters = masm->isolate()->counters();
3177 __ IncrementCounter(counters->string_compare_native(), 1);
3182 __ mov(scratch3, scratch1);
3185 Register length_delta = scratch3;
3189 __ sub(scratch1, length_delta);
3190 __ bind(&left_shorter);
3192 Register min_length = scratch1;
3195 Label compare_lengths;
3196 __ test(min_length, min_length);
3197 __ j(
zero, &compare_lengths, Label::kNear);
3200 Label result_not_equal;
3202 &result_not_equal, Label::kNear);
3205 __ bind(&compare_lengths);
3206 __ test(length_delta, length_delta);
3207 Label length_not_equal;
3208 __ j(
not_zero, &length_not_equal, Label::kNear);
3216 Label result_greater;
3218 __ bind(&length_not_equal);
3219 __ j(
greater, &result_greater, Label::kNear);
3220 __ jmp(&result_less, Label::kNear);
3221 __ bind(&result_not_equal);
3222 __ j(
above, &result_greater, Label::kNear);
3223 __ bind(&result_less);
3230 __ bind(&result_greater);
3237 MacroAssembler* masm, Register left, Register right, Register length,
3238 Register scratch, Label* chars_not_equal,
3239 Label::Distance chars_not_equal_near) {
3243 __ SmiUntag(length);
3249 Register index = length;
3254 __ mov_b(scratch, Operand(left, index,
times_1, 0));
3255 __ cmpb(scratch, Operand(right, index,
times_1, 0));
3256 __ j(
not_equal, chars_not_equal, chars_not_equal_near);
3279 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1);
3285 __ JumpIfNotBothSequentialOneByteStrings(
edx,
eax,
ecx,
ebx, &runtime);
3298 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3302 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
3312 __ mov(
ecx,
handle(isolate()->heap()->undefined_value()));
3315 if (FLAG_debug_code) {
3319 isolate()->factory()->allocation_site_map());
3320 __ Assert(
equal, kExpectedAllocationSite);
3325 BinaryOpWithAllocationSiteStub stub(isolate(), state());
3326 __ TailCallStub(&stub);
3335 __ JumpIfNotSmi(
ecx, &miss, Label::kNear);
3360 Label unordered, maybe_undefined1, maybe_undefined2;
3364 __ JumpIfNotSmi(
edx, &miss);
3367 __ JumpIfNotSmi(
eax, &miss);
3371 Label done,
left, left_smi, right_smi;
3372 __ JumpIfSmi(
eax, &right_smi, Label::kNear);
3374 isolate()->factory()->heap_number_map());
3377 __ jmp(&
left, Label::kNear);
3378 __ bind(&right_smi);
3384 __ JumpIfSmi(
edx, &left_smi, Label::kNear);
3386 isolate()->factory()->heap_number_map());
3411 __ bind(&unordered);
3412 __ bind(&generic_stub);
3417 __ bind(&maybe_undefined1);
3419 __ cmp(
eax, Immediate(isolate()->factory()->undefined_value()));
3421 __ JumpIfSmi(
edx, &unordered);
3427 __ bind(&maybe_undefined2);
3429 __ cmp(
edx, Immediate(isolate()->factory()->undefined_value()));
3445 Register tmp1 =
ecx;
3446 Register tmp2 =
ebx;
3453 __ JumpIfSmi(tmp1, &miss, Label::kNear);
3490 Register tmp1 =
ecx;
3491 Register tmp2 =
ebx;
3498 __ JumpIfSmi(tmp1, &miss, Label::kNear);
3507 __ JumpIfNotUniqueNameInstanceType(tmp1, &miss, Label::kNear);
3508 __ JumpIfNotUniqueNameInstanceType(tmp2, &miss, Label::kNear);
3537 Register tmp1 =
ecx;
3538 Register tmp2 =
ebx;
3539 Register tmp3 =
edi;
3545 __ JumpIfSmi(tmp1, &miss);
3585 __ bind(&do_compare);
3590 __ JumpIfNotBothSequentialOneByteStrings(
left,
right, tmp1, tmp2, &runtime);
3608 __ TailCallRuntime(Runtime::kStringEquals, 2, 1);
3610 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3623 __ JumpIfSmi(
ecx, &miss, Label::kNear);
3643 __ JumpIfSmi(
ecx, &miss, Label::kNear);
3663 ExternalReference miss = ExternalReference(IC_Utility(IC::kCompareIC_Miss),
3671 __ CallExternalReference(miss, 3);
3691 Register properties,
3709 NameDictionary::GetProbeOffset(
i))));
3714 Register entity_name =
r0;
3719 __ cmp(entity_name, masm->isolate()->factory()->undefined_value());
3723 __ cmp(entity_name, Handle<Name>(
name));
3728 __ cmp(entity_name, masm->isolate()->factory()->the_hole_value());
3729 __ j(
equal, &good, Label::kNear);
3733 __ JumpIfNotUniqueNameInstanceType(
3740 __ push(Immediate(Handle<Object>(
name)));
3741 __ push(Immediate(
name->Hash()));
3779 __ add(
r0, Immediate(NameDictionary::GetProbeOffset(
i)));
3788 __ cmp(
name, Operand(elements,
3824 Label in_dictionary, maybe_in_dictionary, not_in_dictionary;
3826 Register scratch =
result();
3830 __ SmiUntag(scratch);
3842 __ add(scratch, Immediate(NameDictionary::GetProbeOffset(
i)));
3844 __ and_(scratch, Operand(
esp, 0));
3854 __ cmp(scratch, isolate()->factory()->undefined_value());
3855 __ j(
equal, ¬_in_dictionary);
3868 __ JumpIfNotUniqueNameInstanceType(
3870 &maybe_in_dictionary);
3874 __ bind(&maybe_in_dictionary);
3884 __ bind(&in_dictionary);
3889 __ bind(¬_in_dictionary);
3910 Label skip_to_incremental_noncompacting;
3911 Label skip_to_incremental_compacting;
3917 __ jmp(&skip_to_incremental_noncompacting, Label::kNear);
3918 __ jmp(&skip_to_incremental_compacting, Label::kFar);
3927 __ bind(&skip_to_incremental_noncompacting);
3930 __ bind(&skip_to_incremental_compacting);
3944 Label dont_need_remembered_set;
3949 &dont_need_remembered_set);
3955 &dont_need_remembered_set);
3968 __ bind(&dont_need_remembered_set);
3983 int argument_count = 3;
3988 Immediate(ExternalReference::isolate_address(isolate())));
3990 AllowExternalCallThatCantCauseGC scope(masm);
3992 ExternalReference::incremental_marking_record_write_function(isolate()),
4000 MacroAssembler* masm,
4001 OnNoNeedToInformIncrementalMarker on_no_need,
4003 Label object_is_black, need_incremental, need_incremental_pop_object;
4032 __ bind(&object_is_black);
4038 Label ensure_not_white;
4054 __ jmp(&need_incremental);
4056 __ bind(&ensure_not_white);
4065 &need_incremental_pop_object,
4077 __ bind(&need_incremental_pop_object);
4080 __ bind(&need_incremental);
4097 Label double_elements;
4099 Label slow_elements;
4100 Label slow_elements_from_double;
4101 Label fast_elements;
4108 __ CheckFastElements(
edi, &double_elements);
4111 __ JumpIfSmi(
eax, &smi_element);
4112 __ CheckFastSmiElements(
edi, &fast_elements, Label::kNear);
4117 __ bind(&slow_elements);
4128 __ TailCallRuntime(Runtime::kStoreArrayLiteralElement, 5, 1);
4130 __ bind(&slow_elements_from_double);
4132 __ jmp(&slow_elements);
4135 __ bind(&fast_elements);
4149 __ bind(&smi_element);
4156 __ bind(&double_elements);
4160 __ StoreNumberToDoubleElements(
eax,
4165 &slow_elements_from_double);
4174 int parameter_count_offset =
4177 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
4179 int additional_offset =
4188 VectorLoadStub stub(isolate(),
state());
4195 VectorKeyedLoadStub stub(isolate());
4201 if (masm->isolate()->function_entry_hook() !=
NULL) {
4203 masm->CallStub(&stub);
4210 const int kNumSavedRegisters = 3;
4226 DCHECK(isolate()->function_entry_hook() !=
NULL);
4241 static void CreateArrayDispatch(MacroAssembler* masm,
4244 T stub(masm->isolate(),
4247 __ TailCallStub(&stub);
4251 for (
int i = 0;
i <= last_index; ++
i) {
4256 T stub(masm->isolate(), kind);
4257 __ TailCallStub(&stub);
4262 __ Abort(kUnexpectedElementsKindInArrayConstructor);
4269 static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
4277 Label normal_sequence;
4294 __ j(
zero, &normal_sequence);
4300 ArraySingleArgumentConstructorStub stub_holey(masm->isolate(),
4303 __ TailCallStub(&stub_holey);
4305 __ bind(&normal_sequence);
4306 ArraySingleArgumentConstructorStub stub(masm->isolate(),
4309 __ TailCallStub(&stub);
4315 if (FLAG_debug_code) {
4316 Handle<Map> allocation_site_map =
4317 masm->isolate()->factory()->allocation_site_map();
4319 __ Assert(
equal, kExpectedAllocationSite);
4329 __ bind(&normal_sequence);
4332 for (
int i = 0;
i <= last_index; ++
i) {
4337 ArraySingleArgumentConstructorStub stub(masm->isolate(), kind);
4338 __ TailCallStub(&stub);
4343 __ Abort(kUnexpectedElementsKindInArrayConstructor);
4351 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
4354 for (
int i = 0;
i <= to_index; ++
i) {
4356 T stub(isolate, kind);
4367 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
4369 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
4371 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
4379 for (
int i = 0;
i < 2;
i++) {
4381 InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[
i]);
4383 InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[
i]);
4385 InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[
i]);
4392 MacroAssembler* masm,
4395 Label not_zero_case, not_one_case;
4398 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm,
mode);
4400 __ bind(¬_zero_case);
4403 CreateArrayDispatchOneArgument(masm,
mode);
4405 __ bind(¬_one_case);
4406 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm,
mode);
4408 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm,
mode);
4410 CreateArrayDispatchOneArgument(masm,
mode);
4412 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm,
mode);
4427 if (FLAG_debug_code) {
4435 __ Assert(
not_zero, kUnexpectedInitialMapForArrayFunction);
4437 __ Assert(
equal, kUnexpectedInitialMapForArrayFunction);
4440 __ AssertUndefinedOrAllocationSite(
ebx);
4446 __ cmp(
ebx, isolate()->factory()->undefined_value());
4463 Label not_zero_case, not_one_case;
4464 Label normal_sequence;
4468 InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
4469 __ TailCallStub(&stub0);
4471 __ bind(¬_zero_case);
4480 __ j(
zero, &normal_sequence);
4482 InternalArraySingleArgumentConstructorStub
4484 __ TailCallStub(&stub1_holey);
4487 __ bind(&normal_sequence);
4488 InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
4489 __ TailCallStub(&stub1);
4491 __ bind(¬_one_case);
4492 InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
4493 __ TailCallStub(&stubN);
4505 if (FLAG_debug_code) {
4513 __ Assert(
not_zero, kUnexpectedInitialMapForArrayFunction);
4515 __ Assert(
equal, kUnexpectedInitialMapForArrayFunction);
4525 __ DecodeField<Map::ElementsKindBits>(
ecx);
4527 if (FLAG_debug_code) {
4533 kInvalidElementsKindForInternalArrayOrInternalPackedArray);
4537 Label fast_elements_case;
4539 __ j(
equal, &fast_elements_case);
4542 __ bind(&fast_elements_case);
4562 Register callee =
eax;
4563 Register call_data =
ebx;
4564 Register holder =
ecx;
4565 Register api_function_address =
edx;
4566 Register return_address =
edi;
4567 Register context =
esi;
4573 typedef FunctionCallbackArguments FCA;
4584 __ pop(return_address);
4597 Register scratch = call_data;
4600 __ push(Immediate(isolate()->factory()->undefined_value()));
4602 __ push(Immediate(isolate()->factory()->undefined_value()));
4610 __ push(Immediate(
reinterpret_cast<int>(isolate())));
4614 __ mov(scratch,
esp);
4617 __ push(return_address);
4623 const int kApiArgc = 1 + 1;
4627 const int kApiStackSpace = 4;
4629 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace);
4645 ExternalReference thunk_ref =
4646 ExternalReference::invoke_function_callback(isolate());
4648 Operand context_restore_operand(
ebp,
4651 int return_value_offset = 0;
4653 return_value_offset = 2 + FCA::kArgsLength;
4655 return_value_offset = 2 + FCA::kReturnValueOffset;
4657 Operand return_value_operand(
ebp, return_value_offset *
kPointerSize);
4658 __ CallApiFunctionAndReturn(api_function_address,
4661 argc + FCA::kArgsLength + 1,
4662 return_value_operand,
4663 &context_restore_operand);
4682 const int kApiArgc = 2 + 1;
4684 Register api_function_address =
edx;
4685 Register scratch =
ebx;
4690 __ PrepareCallApiFunction(kApiArgc);
4695 ExternalReference thunk_ref =
4696 ExternalReference::invoke_accessor_getter_callback(isolate());
4698 __ CallApiFunctionAndReturn(api_function_address,
static AllocationSiteMode GetMode(ElementsKind boilerplate_elements_kind)
static const int kTransitionInfoOffset
static const Register function_address()
static const Register parameter_count()
static const Register index()
void GenerateReadElement(MacroAssembler *masm)
void GenerateNewSloppySlow(MacroAssembler *masm)
void GenerateNewStrict(MacroAssembler *masm)
void GenerateNewSloppyFast(MacroAssembler *masm)
static const int kLengthOffset
static void GenerateStubsAheadOfTime(Isolate *isolate)
void GenerateDispatchToArrayStub(MacroAssembler *masm, AllocationSiteOverrideMode mode)
ArgumentCountKey argument_count() const
static const int kCallInstructionLength
static void GenerateAheadOfTime(Isolate *isolate)
bool save_doubles() const
static void GenerateAheadOfTime(Isolate *isolate)
CEntryStub(Isolate *isolate, int result_size, SaveFPRegsMode save_doubles=kDontSaveFPRegs)
bool NeedsImmovableCode()
bool call_data_undefined() const
STATIC_ASSERT(Code::kArgumentsBits+2<=kStubMinorKeyBits)
bool RecordCallTarget() const
bool CallAsMethod() const
bool CallAsMethod() const
void GenerateMiss(MacroAssembler *masm)
virtual InlineCacheState GetICState() const OVERRIDE
static const int kHeaderSize
Condition GetCondition() const
void GenerateInternalizedStrings(MacroAssembler *masm)
void GenerateStrings(MacroAssembler *masm)
CompareICState::State state() const
void GenerateMiss(MacroAssembler *masm)
CompareICState::State left() const
void GenerateGeneric(MacroAssembler *masm)
CompareICState::State right() const
void GenerateObjects(MacroAssembler *masm)
CompareICStub(Isolate *isolate, Token::Value op, CompareICState::State left, CompareICState::State right, CompareICState::State state)
void GenerateNumbers(MacroAssembler *masm)
void GenerateUniqueNames(MacroAssembler *masm)
void GenerateKnownObjects(MacroAssembler *masm)
void GenerateSmis(MacroAssembler *masm)
static const int kFirstOffset
static const int kMinLength
static const int kSecondOffset
@ SLOPPY_ARGUMENTS_MAP_INDEX
@ STRICT_ARGUMENTS_MAP_INDEX
@ ALIASED_ARGUMENTS_MAP_INDEX
static int SlotOffset(int index)
static bool IsSupported(CpuFeature f)
static void GenerateAheadOfTime(Isolate *isolate)
bool is_truncating() const
STATIC_ASSERT((1L<< kBitsPerRegisterNumber) >=Register::kNumRegisters)
Register destination() const
static const uint64_t kSignificandMask
static const uint64_t kHiddenBit
static const int kPhysicalSignificandSize
static const int kMaxShortLength
static const int kResourceDataOffset
static const int kLengthOffset
static const int kHeaderSize
static const int kNativeContextOffset
static const int kEntrySize
static const int kMantissaBits
static const int kValueOffset
static const uint32_t kExponentMask
static const int kExponentBias
static const int kExponentShift
static const int kMapOffset
static const int kStrictArgumentsObjectSize
static const int kSloppyArgumentsObjectSize
static const int kArgumentsCalleeIndex
static const int kArgumentsLengthIndex
void GenerateLightweightMiss(MacroAssembler *masm, ExternalReference miss)
bool HasCallSiteInlineCheck() const
bool HasArgsInRegisters() const
bool ReturnTrueFalseObject() const
static void GenerateStubsAheadOfTime(Isolate *isolate)
void GenerateCase(MacroAssembler *masm, ElementsKind kind)
static const int kJSRegexpStaticOffsetsVectorSize
StackFrame::Type type() const
static const int kSharedFunctionInfoOffset
static const int kContextOffset
static const int kLiteralsOffset
static const int kPrototypeOrInitialMapOffset
static const int kHeaderSize
static const int kPropertiesOffset
static const int kElementsOffset
static const int kDataOneByteCodeOffset
static const int kIrregexpCaptureCountOffset
static const int kDataTagOffset
static const int kDataOffset
static const int kDataUC16CodeOffset
static const int kFunctionOffset
static const Register ReceiverRegister()
static const Register NameRegister()
LoadICState state() const
static const int kIsUndetectable
static const int kBitFieldOffset
static const int kInstanceTypeOffset
static const int kBitField2Offset
static const int kPrototypeOffset
ExponentType exponent_type() const
static const Register exponent()
static const size_t kWriteBarrierCounterOffset
static const int kEvacuationCandidateMask
static const int kSkipEvacuationSlotsRecordingMask
static const int kElementsStartOffset
NameDictionaryLookupStub(Isolate *isolate, LookupMode mode)
static const int kCapacityOffset
Register dictionary() const
static void GeneratePositiveLookup(MacroAssembler *masm, Label *miss, Label *done, Register elements, Register name, Register r0, Register r1)
static const int kTotalProbes
static const int kInlinedProbes
static void GenerateNegativeLookup(MacroAssembler *masm, Label *miss, Label *done, Register receiver, Register properties, Handle< Name > name, Register scratch0)
static const int kHashShift
static const int kEmptyHashField
static const int kHashFieldOffset
static void GenerateLoadFunctionPrototype(MacroAssembler *masm, Register receiver, Register scratch1, Register scratch2, Label *miss_label)
static const intptr_t kPageAlignmentMask
ProfileEntryHookStub(Isolate *isolate)
static void MaybeCallEntryHook(MacroAssembler *masm)
static const int kArgsLength
void Restore(MacroAssembler *masm)
void SaveCallerSaveRegisters(MacroAssembler *masm, SaveFPRegsMode mode)
void Save(MacroAssembler *masm)
void RestoreCallerSaveRegisters(MacroAssembler *masm, SaveFPRegsMode mode)
void GenerateIncremental(MacroAssembler *masm, Mode mode)
void InformIncrementalMarker(MacroAssembler *masm)
RememberedSetAction remembered_set_action() const
SaveFPRegsMode save_fp_regs_mode() const
@ kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
@ kReturnOnNoNeedToInformIncrementalMarker
static const byte kTwoByteNopInstruction
void CheckNeedsToInformIncrementalMarker(MacroAssembler *masm, OnNoNeedToInformIncrementalMarker on_no_need, Mode mode)
static const byte kFiveByteNopInstruction
virtual void Generate(MacroAssembler *masm) OVERRIDE
static const int kLastCaptureCountOffset
static const int kLastSubjectOffset
static const int kLastMatchOverhead
static const int kLastInputOffset
static const int kFirstCaptureOffset
static const Function * FunctionForId(FunctionId id)
static const int kHeaderSize
static const int kConstructStubOffset
static const int kFeedbackVectorOffset
static const int kNativeBitWithinByte
static const int kStrictModeBitWithinByte
static const int kMinLength
static const int kParentOffset
static const int kOffsetOffset
static Smi * FromInt(int value)
static const int kContextOffset
static const int kCallerSPOffset
static const int kCallerFPOffset
static void GenerateFixedRegStubsAheadOfTime(Isolate *isolate)
StoreBufferOverflowStub(Isolate *isolate, SaveFPRegsMode save_fp)
bool save_doubles() const
StringIndexFlags index_flags_
Label * receiver_not_string_
Label * index_out_of_range_
void GenerateFast(MacroAssembler *masm)
Label * index_not_number_
void GenerateSlow(MacroAssembler *masm, const RuntimeCallHelper &call_helper)
void GenerateFast(MacroAssembler *masm)
void GenerateSlow(MacroAssembler *masm, const RuntimeCallHelper &call_helper)
static void Generate(MacroAssembler *masm, Register string, Register index, Register result, Label *call_runtime)
static void GenerateOneByteCharsCompareLoop(MacroAssembler *masm, Register left, Register right, Register length, Register scratch1, Register scratch2, Label *chars_not_equal)
static void GenerateCompareFlatOneByteStrings(MacroAssembler *masm, Register left, Register right, Register scratch1, Register scratch2, Register scratch3, Register scratch4)
static void GenerateCopyCharacters(MacroAssembler *masm, Register dest, Register src, Register count, Register scratch, String::Encoding encoding)
static void GenerateFlatOneByteStringEquals(MacroAssembler *masm, Register left, Register right, Register scratch1, Register scratch2, Register scratch3)
static const int32_t kMaxOneByteCharCode
static const int kLengthOffset
static const int kCallerStackParameterCountFrameOffset
StubFunctionMode function_mode() const
static void GenerateAheadOfTime(Isolate *isolate)
static bool IsOrderedRelationalCompareOp(Value op)
static bool IsEqualityOp(Value op)
static Handle< Object > UninitializedSentinel(Isolate *isolate)
static Handle< Object > MegamorphicSentinel(Isolate *isolate)
static const Register VectorRegister()
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
bool IsPowerOfTwo32(uint32_t value)
const uint32_t kStringEncodingMask
ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number)
@ DONT_TRACK_ALLOCATION_SITE
const intptr_t kSmiSignMask
const uint32_t kTwoByteStringTag
const uint32_t kShortExternalStringTag
const int kFastElementsKindPackedToHoley
const uint32_t kNotStringTag
Operand FieldOperand(Register object, int offset)
const uint32_t kStringTag
@ FAST_HOLEY_DOUBLE_ELEMENTS
@ TERMINAL_FAST_ELEMENTS_KIND
@ FAST_HOLEY_SMI_ELEMENTS
Handle< T > handle(T *t, Isolate *isolate)
const uint32_t kOneByteStringTag
@ TREAT_MINUS_ZERO_AS_ZERO
int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind)
bool IsFastPackedElementsKind(ElementsKind kind)
const uint32_t kShortExternalStringMask
ElementsKind GetHoleyElementsKind(ElementsKind packed_kind)
AllocationSiteOverrideMode
@ DISABLE_ALLOCATION_SITES
Condition NegateCondition(Condition cond)
@ times_half_pointer_size
const uint32_t kStringRepresentationMask
const uint32_t kSlicedNotConsMask
OStream & dec(OStream &os)
const uint32_t kInternalizedTag
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
const intptr_t kSmiTagMask
const uint32_t kIsNotInternalizedMask
Operand ApiParameterOperand(int index)
const uint32_t kIsNotStringMask
ElementsKind GetInitialFastElementsKind()
@ STRING_INDEX_IS_ARRAY_INDEX
const uint32_t kIsIndirectStringMask
Debugger support for the V8 JavaScript engine.
static Handle< Value > Throw(Isolate *isolate, const char *message)
bool is(Register reg) const
static const int kMaxNumRegisters
static XMMRegister from_code(int code)
#define T(name, string, precedence)