24 static void InitializeArrayConstructorDescriptor(
25 Isolate* isolate, CodeStubDescriptor* descriptor,
26 int constant_stack_parameter_count) {
28 Runtime::kArrayConstructor)->
entry;
30 if (constant_stack_parameter_count == 0) {
31 descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
34 descriptor->Initialize(
r0, deopt_handler, constant_stack_parameter_count,
40 static void InitializeInternalArrayConstructorDescriptor(
41 Isolate* isolate, CodeStubDescriptor* descriptor,
42 int constant_stack_parameter_count) {
44 Runtime::kInternalArrayConstructor)->
entry;
46 if (constant_stack_parameter_count == 0) {
47 descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
50 descriptor->Initialize(
r0, deopt_handler, constant_stack_parameter_count,
56 void ArrayNoArgumentConstructorStub::InitializeDescriptor(
57 CodeStubDescriptor* descriptor) {
58 InitializeArrayConstructorDescriptor(isolate(), descriptor, 0);
62 void ArraySingleArgumentConstructorStub::InitializeDescriptor(
63 CodeStubDescriptor* descriptor) {
64 InitializeArrayConstructorDescriptor(isolate(), descriptor, 1);
68 void ArrayNArgumentsConstructorStub::InitializeDescriptor(
69 CodeStubDescriptor* descriptor) {
70 InitializeArrayConstructorDescriptor(isolate(), descriptor, -1);
74 void InternalArrayNoArgumentConstructorStub::InitializeDescriptor(
75 CodeStubDescriptor* descriptor) {
76 InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, 0);
80 void InternalArraySingleArgumentConstructorStub::InitializeDescriptor(
81 CodeStubDescriptor* descriptor) {
82 InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, 1);
86 void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
87 CodeStubDescriptor* descriptor) {
88 InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1);
92 #define __ ACCESS_MASM(masm)
95 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
98 static void EmitSmiNonsmiComparison(MacroAssembler* masm,
104 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
110 ExternalReference miss) {
112 isolate()->counters()->code_stubs()->Increment();
114 CallInterfaceDescriptor descriptor = GetCallInterfaceDescriptor();
115 int param_count = descriptor.GetEnvironmentParameterCount();
119 DCHECK(param_count == 0 ||
120 r0.
is(descriptor.GetEnvironmentParameterRegister(param_count - 1)));
122 for (
int i = 0;
i < param_count; ++
i) {
123 __ push(descriptor.GetEnvironmentParameterRegister(
i));
125 __ CallExternalReference(miss, param_count);
133 Label out_of_range, only_low, negate, done;
134 Register input_reg =
source();
138 int double_offset =
offset();
143 Register scratch_low =
145 Register scratch_high =
149 __ Push(scratch_high, scratch_low, scratch);
153 __ vldr(double_scratch,
MemOperand(input_reg, double_offset));
154 __ vmov(scratch_low, scratch_high, double_scratch);
157 __ vcvt_s32_f64(double_scratch.low(), double_scratch);
158 __ vmov(result_reg, double_scratch.low());
161 __ sub(scratch, result_reg, Operand(1));
162 __ cmp(scratch, Operand(0x7ffffffe));
167 if (double_offset == 0) {
168 __ ldm(
ia, input_reg, scratch_low.bit() | scratch_high.bit());
170 __ ldr(scratch_low,
MemOperand(input_reg, double_offset));
175 __ Ubfx(scratch, scratch_high,
185 __ cmp(scratch, Operand(83));
186 __ b(
ge, &out_of_range);
193 __ rsb(scratch, scratch, Operand(51),
SetCC);
197 __ mov(scratch_low, Operand(scratch_low,
LSR, scratch));
201 __ rsb(scratch, scratch, Operand(32));
202 __ Ubfx(result_reg, scratch_high,
205 __ orr(result_reg, result_reg,
207 __ orr(result_reg, scratch_low, Operand(result_reg,
LSL, scratch));
210 __ bind(&out_of_range);
211 __ mov(result_reg, Operand::Zero());
217 __ rsb(scratch, scratch, Operand::Zero());
218 __ mov(result_reg, Operand(scratch_low,
LSL, scratch));
227 __ eor(result_reg, result_reg, Operand(scratch_high,
ASR, 31));
228 __ add(result_reg, result_reg, Operand(scratch_high,
LSR, 31));
232 __ Pop(scratch_high, scratch_low, scratch);
248 Label max_negative_int;
254 __ b(
eq, &max_negative_int);
259 __ mov(
scratch(), Operand(non_smi_exponent));
278 __ bind(&max_negative_int);
286 __ mov(
ip, Operand::Zero());
295 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
299 Label heap_number, return_equal;
301 __ b(
ne, ¬_identical);
307 if (cond ==
lt || cond ==
gt) {
312 __ b(
eq, &heap_number);
320 if (cond ==
le || cond ==
ge) {
322 __ b(
ne, &return_equal);
323 __ LoadRoot(
r2, Heap::kUndefinedValueRootIndex);
325 __ b(
ne, &return_equal);
338 __ bind(&return_equal);
341 }
else if (cond ==
gt) {
351 if (cond !=
lt && cond !=
gt) {
352 __ bind(&heap_number);
363 __ cmp(
r3, Operand(-1));
364 __ b(
ne, &return_equal);
388 __ bind(¬_identical);
393 static void EmitSmiNonsmiComparison(MacroAssembler* masm,
400 (lhs.is(
r1) && rhs.is(
r0)));
403 __ JumpIfSmi(rhs, &rhs_is_smi);
423 __ SmiToDouble(
d7, lhs);
431 __ bind(&rhs_is_smi);
452 __ SmiToDouble(
d6, rhs);
458 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
462 (lhs.is(
r1) && rhs.is(
r0)));
468 Label first_non_object;
472 __ b(
lt, &first_non_object);
475 Label return_not_equal;
476 __ bind(&return_not_equal);
479 __ bind(&first_non_object);
482 __ b(
eq, &return_not_equal);
485 __ b(
ge, &return_not_equal);
489 __ b(
eq, &return_not_equal);
496 __ b(
eq, &return_not_equal);
501 static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm,
504 Label* both_loaded_as_doubles,
505 Label* not_heap_numbers,
508 (lhs.is(
r1) && rhs.is(
r0)));
511 __ b(
ne, not_heap_numbers);
520 __ jmp(both_loaded_as_doubles);
525 static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm,
528 Label* possible_strings,
529 Label* not_both_strings) {
531 (lhs.is(
r1) && rhs.is(
r0)));
537 __ b(
ne, &object_test);
539 __ b(
ne, possible_strings);
541 __ b(
ge, not_both_strings);
543 __ b(
ne, possible_strings);
550 __ bind(&object_test);
552 __ b(
lt, not_both_strings);
554 __ b(
lt, not_both_strings);
568 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input,
574 __ JumpIfNotSmi(input, fail);
576 __ JumpIfSmi(input, &ok);
577 __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail,
595 CompareICStub_CheckInputType(masm, lhs,
r2,
left(), &miss);
596 CompareICStub_CheckInputType(masm, rhs,
r3,
right(), &miss);
599 Label not_smis, both_loaded_as_doubles, lhs_not_nan;
601 Label not_two_smis, smi_done;
603 __ JumpIfNotSmi(
r2, ¬_two_smis);
607 __ bind(¬_two_smis);
614 EmitIdenticalObjectComparison(masm, &slow,
cc);
620 __ and_(
r2, lhs, Operand(rhs));
621 __ JumpIfNotSmi(
r2, ¬_smis);
631 EmitSmiNonsmiComparison(masm, lhs, rhs, &lhs_not_nan, &slow,
strict());
633 __ bind(&both_loaded_as_doubles);
636 __ bind(&lhs_not_nan);
639 __ VFPCompareAndSetFlags(
d7,
d6);
664 EmitStrictTwoHeapObjectCompare(masm, lhs, rhs);
667 Label check_for_internalized_strings;
668 Label flat_string_check;
674 EmitCheckForTwoHeapNumbers(masm,
677 &both_loaded_as_doubles,
678 &check_for_internalized_strings,
681 __ bind(&check_for_internalized_strings);
688 EmitCheckForInternalizedStringsOrObjects(
689 masm, lhs, rhs, &flat_string_check, &slow);
694 __ bind(&flat_string_check);
696 __ JumpIfNonSmisNotBothSequentialOneByteStrings(lhs, rhs,
r2,
r3, &slow);
698 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1,
r2,
714 native =
strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
716 native = Builtins::COMPARE;
743 const Register scratch =
r1;
746 __ SaveFPRegs(
sp, scratch);
748 const int argument_count = 1;
749 const int fp_argument_count = 0;
751 AllowExternalCallThatCantCauseGC scope(masm);
752 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch);
753 __ mov(
r0, Operand(ExternalReference::isolate_address(isolate())));
755 ExternalReference::store_buffer_overflow_function(isolate()),
758 __ RestoreFPRegs(
sp, scratch);
765 const Register base =
r1;
768 const Register heapnumbermap =
r5;
769 const Register heapnumber =
r0;
770 const DwVfpRegister double_base =
d0;
771 const DwVfpRegister double_exponent =
d1;
772 const DwVfpRegister double_result =
d2;
773 const DwVfpRegister double_scratch =
d3;
774 const SwVfpRegister single_scratch =
s6;
775 const Register scratch =
r9;
776 const Register scratch2 =
r4;
778 Label call_runtime, done, int_exponent;
780 Label base_is_smi, unpack_exponent;
787 __ LoadRoot(heapnumbermap, Heap::kHeapNumberMapRootIndex);
789 __ UntagAndJumpIfSmi(scratch, base, &base_is_smi);
791 __ cmp(scratch, heapnumbermap);
792 __ b(
ne, &call_runtime);
795 __ jmp(&unpack_exponent);
797 __ bind(&base_is_smi);
798 __ vmov(single_scratch, scratch);
799 __ vcvt_f64_s32(double_base, single_scratch);
800 __ bind(&unpack_exponent);
802 __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent);
805 __ cmp(scratch, heapnumbermap);
806 __ b(
ne, &call_runtime);
807 __ vldr(double_exponent,
811 __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent);
813 __ vldr(double_exponent,
818 Label int_exponent_convert;
820 __ vcvt_u32_f64(single_scratch, double_exponent);
823 __ vcvt_f64_u32(double_scratch, single_scratch);
824 __ VFPCompareAndSetFlags(double_scratch, double_exponent);
825 __ b(
eq, &int_exponent_convert);
834 __ vmov(double_scratch, 0.5, scratch);
835 __ VFPCompareAndSetFlags(double_exponent, double_scratch);
836 __ b(
ne, ¬_plus_half);
841 __ VFPCompareAndSetFlags(double_base, double_scratch);
842 __ vneg(double_result, double_scratch,
eq);
847 __ vsqrt(double_result, double_scratch);
850 __ bind(¬_plus_half);
851 __ vmov(double_scratch, -0.5, scratch);
852 __ VFPCompareAndSetFlags(double_exponent, double_scratch);
853 __ b(
ne, &call_runtime);
858 __ VFPCompareAndSetFlags(double_base, double_scratch);
864 __ vmov(double_result, 1.0, scratch);
865 __ vsqrt(double_scratch, double_scratch);
866 __ vdiv(double_result, double_result, double_scratch);
872 AllowExternalCallThatCantCauseGC scope(masm);
873 __ PrepareCallCFunction(0, 2, scratch);
874 __ MovToFloatParameters(double_base, double_exponent);
876 ExternalReference::power_double_double_function(isolate()),
880 __ MovFromFloatResult(double_result);
883 __ bind(&int_exponent_convert);
884 __ vcvt_u32_f64(single_scratch, double_exponent);
885 __ vmov(scratch, single_scratch);
889 __ bind(&int_exponent);
893 __ mov(scratch, exponent);
896 __ mov(exponent, scratch);
898 __ vmov(double_scratch, double_base);
899 __ vmov(double_result, 1.0, scratch2);
902 __ cmp(scratch, Operand::Zero());
907 __ bind(&while_true);
908 __ mov(scratch, Operand(scratch,
ASR, 1),
SetCC);
909 __ vmul(double_result, double_result, double_scratch,
cs);
910 __ vmul(double_scratch, double_scratch, double_scratch,
ne);
911 __ b(
ne, &while_true);
913 __ cmp(exponent, Operand::Zero());
915 __ vmov(double_scratch, 1.0, scratch);
916 __ vdiv(double_result, double_scratch, double_result);
919 __ VFPCompareAndSetFlags(double_result, 0.0);
923 __ vmov(single_scratch, exponent);
924 __ vcvt_f64_s32(double_exponent, single_scratch);
927 Counters* counters = isolate()->counters();
930 __ bind(&call_runtime);
931 __ TailCallRuntime(Runtime::kMathPowRT, 2, 1);
936 __ AllocateHeapNumber(
937 heapnumber, scratch, scratch2, heapnumbermap, &call_runtime);
938 __ vstr(double_result,
941 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2);
946 AllowExternalCallThatCantCauseGC scope(masm);
947 __ PrepareCallCFunction(0, 2, scratch);
948 __ MovToFloatParameters(double_base, double_exponent);
950 ExternalReference::power_double_double_function(isolate()),
954 __ MovFromFloatResult(double_result);
957 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2);
968 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
976 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
980 void CodeStub::GenerateFPStubs(Isolate* isolate) {
983 CEntryStub(isolate, 1,
mode).GetCode();
984 StoreBufferOverflowStub(isolate,
mode).GetCode();
985 isolate->set_fp_stubs_generated(
true);
1012 FrameScope scope(masm, StackFrame::MANUAL);
1024 #if V8_HOST_ARCH_ARM
1026 int frame_alignment_mask = frame_alignment - 1;
1027 if (FLAG_debug_code) {
1029 Label alignment_as_expected;
1031 __ tst(
sp, Operand(frame_alignment_mask));
1032 __ b(
eq, &alignment_as_expected);
1034 __ stop(
"Unexpected alignment");
1035 __ bind(&alignment_as_expected);
1042 __ mov(
r2, Operand(ExternalReference::isolate_address(isolate())));
1054 __ add(
lr,
pc, Operand(4));
1059 __ VFPEnsureFPSCRState(
r2);
1063 if (FLAG_debug_code) {
1065 __ CompareRoot(
r0, Heap::kTheHoleValueRootIndex);
1067 __ stop(
"The hole escaped");
1072 Label exception_returned;
1073 __ CompareRoot(
r0, Heap::kExceptionRootIndex);
1074 __ b(
eq, &exception_returned);
1076 ExternalReference pending_exception_address(
1077 Isolate::kPendingExceptionAddress, isolate());
1081 if (FLAG_debug_code) {
1083 __ mov(
r2, Operand(pending_exception_address));
1085 __ CompareRoot(
r2, Heap::kTheHoleValueRootIndex);
1088 __ stop(
"Unexpected pending exception");
1101 __ bind(&exception_returned);
1104 __ mov(
r2, Operand(pending_exception_address));
1108 __ LoadRoot(
r3, Heap::kTheHoleValueRootIndex);
1113 Label throw_termination_exception;
1114 __ CompareRoot(
r0, Heap::kTerminationExceptionRootIndex);
1115 __ b(
eq, &throw_termination_exception);
1120 __ bind(&throw_termination_exception);
1121 __ ThrowUncatchable(
r0);
1132 Label invoke, handler_entry, exit;
1145 __ VFPEnsureFPSCRState(
r4);
1164 int marker =
type();
1165 if (FLAG_enable_ool_constant_pool) {
1166 __ mov(
r8, Operand(isolate()->factory()->empty_constant_pool_array()));
1171 Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
1173 __ mov(
ip, Operand(-1));
1175 (FLAG_enable_ool_constant_pool ?
r8.
bit() : 0) |
1182 Label non_outermost_js;
1183 ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate());
1184 __ mov(
r5, Operand(ExternalReference(js_entry_sp)));
1186 __ cmp(
r6, Operand::Zero());
1187 __ b(
ne, &non_outermost_js);
1192 __ bind(&non_outermost_js);
1206 __ bind(&handler_entry);
1212 __ mov(
ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
1216 __ LoadRoot(
r0, Heap::kExceptionRootIndex);
1223 __ PushTryHandler(StackHandler::JS_ENTRY, 0);
1230 __ mov(
r5, Operand(isolate()->factory()->the_hole_value()));
1231 __ mov(
ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
1245 if (
type() == StackFrame::ENTRY_CONSTRUCT) {
1246 ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
1248 __ mov(
ip, Operand(construct_entry));
1250 ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
1251 __ mov(
ip, Operand(entry));
1264 Label non_outermost_js_2;
1267 __ b(
ne, &non_outermost_js_2);
1268 __ mov(
r6, Operand::Zero());
1269 __ mov(
r5, Operand(ExternalReference(js_entry_sp)));
1271 __ bind(&non_outermost_js_2);
1276 Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
1284 if (FLAG_debug_code) {
1309 const Register
object =
r0;
1311 const Register
function =
r1;
1312 const Register prototype =
r4;
1313 const Register scratch =
r2;
1315 Label slow, loop, is_instance, is_not_instance, not_js_object;
1323 __ JumpIfSmi(
object, ¬_js_object);
1324 __ IsObjectJSObjectType(
object,
map, scratch, ¬_js_object);
1330 __ CompareRoot(
function, Heap::kInstanceofCacheFunctionRootIndex);
1332 __ CompareRoot(
map, Heap::kInstanceofCacheMapRootIndex);
1334 __ LoadRoot(
r0, Heap::kInstanceofCacheAnswerRootIndex);
1341 __ TryGetFunctionPrototype(
function, prototype, scratch, &slow,
true);
1344 __ JumpIfSmi(prototype, &slow);
1345 __ IsObjectJSObjectType(prototype, scratch, scratch, &slow);
1350 __ StoreRoot(
function, Heap::kInstanceofCacheFunctionRootIndex);
1351 __ StoreRoot(
map, Heap::kInstanceofCacheMapRootIndex);
1358 const Register map_load_offset =
r5;
1359 __ sub(
r9,
lr, map_load_offset);
1361 __ GetRelocatedValueLocation(
r9, map_load_offset, scratch);
1371 Register scratch2 =
map;
1375 __ LoadRoot(scratch2, Heap::kNullValueRootIndex);
1377 __ cmp(scratch, Operand(prototype));
1378 __ b(
eq, &is_instance);
1379 __ cmp(scratch, scratch2);
1380 __ b(
eq, &is_not_instance);
1384 Factory* factory = isolate()->factory();
1386 __ bind(&is_instance);
1389 __ StoreRoot(
r0, Heap::kInstanceofCacheAnswerRootIndex);
1391 __ Move(
r0, factory->true_value());
1395 __ LoadRoot(
r0, Heap::kTrueValueRootIndex);
1398 const Register bool_load_offset =
r6;
1399 __ sub(
r9,
lr, bool_load_offset);
1401 __ GetRelocatedValueLocation(
r9, scratch, scratch2);
1410 __ bind(&is_not_instance);
1413 __ StoreRoot(
r0, Heap::kInstanceofCacheAnswerRootIndex);
1415 __ Move(
r0, factory->false_value());
1419 __ LoadRoot(
r0, Heap::kFalseValueRootIndex);
1422 const Register bool_load_offset =
r6;
1423 __ sub(
r9,
lr, bool_load_offset);
1426 __ GetRelocatedValueLocation(
r9, scratch, scratch2);
1435 Label object_not_null, object_not_null_or_smi;
1436 __ bind(¬_js_object);
1439 __ JumpIfSmi(
function, &slow);
1444 __ cmp(scratch, Operand(isolate()->factory()->null_value()));
1445 __ b(
ne, &object_not_null);
1447 __ Move(
r0, factory->false_value());
1453 __ bind(&object_not_null);
1455 __ JumpIfNotSmi(
object, &object_not_null_or_smi);
1457 __ Move(
r0, factory->false_value());
1463 __ bind(&object_not_null_or_smi);
1465 __ IsObjectJSStringType(
object, scratch, &slow);
1467 __ Move(
r0, factory->false_value());
1486 __ cmp(
r0, Operand::Zero());
1487 __ LoadRoot(
r0, Heap::kTrueValueRootIndex,
eq);
1488 __ LoadRoot(
r0, Heap::kFalseValueRootIndex,
ne);
1501 PropertyAccessCompiler::TailCallBuiltin(
1502 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
1509 const int kDisplacement =
1516 __ JumpIfNotSmi(
r1, &slow);
1533 __ add(
r3,
fp, Operand::PointerOffsetFromSmiKey(
r3));
1547 __ add(
r3,
r2, Operand::PointerOffsetFromSmiKey(
r3));
1555 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1);
1579 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
1597 Label adaptor_frame, try_allocate;
1601 __ b(
eq, &adaptor_frame);
1605 __ b(&try_allocate);
1608 __ bind(&adaptor_frame);
1620 __ bind(&try_allocate);
1624 const int kParameterMapHeaderSize =
1645 const int kNormalOffset =
1647 const int kAliasedOffset =
1652 __ cmp(
r1, Operand::Zero());
1661 __ LoadRoot(
r3, Heap::kEmptyFixedArrayRootIndex);
1668 __ AssertNotSmi(
r3);
1691 Label skip_parameter_map;
1696 __ b(
eq, &skip_parameter_map);
1698 __ LoadRoot(
r6, Heap::kSloppyArgumentsElementsMapRootIndex);
1704 __ add(
r6,
r6, Operand(kParameterMapHeaderSize));
1715 Label parameters_loop, parameters_test;
1720 __ LoadRoot(
r5, Heap::kTheHoleValueRootIndex);
1722 __ add(
r3,
r3, Operand(kParameterMapHeaderSize));
1731 __ jmp(¶meters_test);
1733 __ bind(¶meters_loop);
1741 __ bind(¶meters_test);
1743 __ b(
ne, ¶meters_loop);
1748 __ bind(&skip_parameter_map);
1754 __ LoadRoot(
r5, Heap::kFixedArrayMapRootIndex);
1758 Label arguments_loop, arguments_test;
1762 __ jmp(&arguments_test);
1764 __ bind(&arguments_loop);
1771 __ bind(&arguments_test);
1773 __ b(
lt, &arguments_loop);
1784 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
1796 __ NonNegativeSmiTst(key);
1803 __ TailCallExternalReference(
1804 ExternalReference(IC_Utility(IC::kLoadElementWithInterceptor),
1809 PropertyAccessCompiler::TailCallBuiltin(
1810 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
1819 Label adaptor_frame, try_allocate, runtime;
1823 __ b(
eq, &adaptor_frame);
1827 __ b(&try_allocate);
1830 __ bind(&adaptor_frame);
1833 __ add(
r3,
r2, Operand::PointerOffsetFromSmiKey(
r1));
1839 Label add_arguments_object;
1840 __ bind(&try_allocate);
1842 __ b(
eq, &add_arguments_object);
1844 __ bind(&add_arguments_object);
1858 __ LoadRoot(
r3, Heap::kEmptyFixedArrayRootIndex);
1871 __ cmp(
r1, Operand::Zero());
1881 __ LoadRoot(
r3, Heap::kFixedArrayMapRootIndex);
1896 __ sub(
r1,
r1, Operand(1));
1897 __ cmp(
r1, Operand::Zero());
1907 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1);
1915 #ifdef V8_INTERPRETED_REGEXP
1916 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1);
1936 Register subject =
r4;
1937 Register regexp_data =
r5;
1938 Register last_match_info_elements =
no_reg;
1941 ExternalReference address_of_regexp_stack_memory_address =
1942 ExternalReference::address_of_regexp_stack_memory_address(isolate());
1943 ExternalReference address_of_regexp_stack_memory_size =
1944 ExternalReference::address_of_regexp_stack_memory_size(isolate());
1945 __ mov(
r0, Operand(address_of_regexp_stack_memory_size));
1947 __ cmp(
r0, Operand::Zero());
1952 __ JumpIfSmi(
r0, &runtime);
1958 if (FLAG_debug_code) {
1959 __ SmiTst(regexp_data);
1960 __ Check(
ne, kUnexpectedTypeForRegExpDataFixedArrayExpected);
1962 __ Check(
eq, kUnexpectedTypeForRegExpDataFixedArrayExpected);
1985 __ mov(
r9, Operand::Zero());
1987 __ JumpIfSmi(subject, &runtime);
1988 __ mov(
r3, subject);
2012 Label seq_string , external_string ,
2013 check_underlying , not_seq_nor_cons ,
2024 __ b(
eq, &seq_string);
2032 __ b(
ge, ¬_seq_nor_cons);
2037 __ CompareRoot(
r0, Heap::kempty_stringRootIndex);
2042 __ bind(&check_underlying);
2050 __ b(
ne, &external_string);
2053 __ bind(&seq_string);
2060 __ JumpIfNotSmi(
r1, &runtime);
2079 __ JumpIfSmi(
r6, &runtime);
2087 __ IncrementCounter(isolate()->counters()->regexp_entry_native(), 1,
r0,
r2);
2090 const int kRegExpExecuteArguments = 9;
2091 const int kParameterRegisters = 4;
2092 __ EnterExitFrame(
false, kRegExpExecuteArguments - kParameterRegisters);
2098 __ mov(
r0, Operand(ExternalReference::isolate_address(isolate())));
2102 __ mov(
r0, Operand(1));
2106 __ mov(
r0, Operand(address_of_regexp_stack_memory_address));
2108 __ mov(
r2, Operand(address_of_regexp_stack_memory_size));
2115 __ mov(
r0, Operand::Zero());
2120 Operand(ExternalReference::address_of_static_offsets_vector(
2127 __ eor(
r3,
r3, Operand(1));
2148 __ mov(
r0, subject);
2152 DirectCEntryStub stub(isolate());
2153 stub.GenerateCall(masm,
r6);
2155 __ LeaveExitFrame(
false,
no_reg,
true);
2157 last_match_info_elements =
r6;
2165 __ cmp(
r0, Operand(1));
2179 __ mov(
r1, Operand(isolate()->factory()->the_hole_value()));
2180 __ mov(
r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
2189 __ CompareRoot(
r0, Heap::kTerminationExceptionRootIndex);
2191 Label termination_exception;
2192 __ b(
eq, &termination_exception);
2196 __ bind(&termination_exception);
2197 __ ThrowUncatchable(
r0);
2201 __ mov(
r0, Operand(isolate()->factory()->null_value()));
2213 __ add(
r1,
r1, Operand(2));
2216 __ JumpIfSmi(
r0, &runtime);
2220 __ ldr(last_match_info_elements,
2223 __ CompareRoot(
r0, Heap::kFixedArrayMapRootIndex);
2230 __ cmp(
r2, Operand::SmiUntag(
r0));
2243 __ mov(
r2, subject);
2244 __ RecordWriteField(last_match_info_elements,
2250 __ mov(subject,
r2);
2254 __ RecordWriteField(last_match_info_elements,
2262 ExternalReference address_of_static_offsets_vector =
2263 ExternalReference::address_of_static_offsets_vector(isolate());
2264 __ mov(
r2, Operand(address_of_static_offsets_vector));
2268 Label next_capture, done;
2272 last_match_info_elements,
2274 __ bind(&next_capture);
2282 __ jmp(&next_capture);
2292 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1);
2296 __ bind(¬_seq_nor_cons);
2298 __ b(
gt, ¬_long_external);
2301 __ bind(&external_string);
2304 if (FLAG_debug_code) {
2308 __ Assert(
eq, kExternalStringExpectedButNotFound);
2317 __ jmp(&seq_string);
2320 __ bind(¬_long_external);
2330 __ jmp(&check_underlying);
2335 static void GenerateRecordCallTarget(MacroAssembler* masm) {
2343 Label initialize, done, miss, megamorphic, not_array_function;
2346 masm->isolate()->heap()->megamorphic_symbol());
2348 masm->isolate()->heap()->uninitialized_symbol());
2351 __ add(
r4,
r2, Operand::PointerOffsetFromSmiKey(
r3));
2359 if (!FLAG_pretenuring_call_new) {
2365 __ CompareRoot(
r5, Heap::kAllocationSiteMapRootIndex);
2371 __ b(
ne, &megamorphic);
2379 __ CompareRoot(
r4, Heap::kUninitializedSymbolRootIndex);
2380 __ b(
eq, &initialize);
2383 __ bind(&megamorphic);
2384 __ add(
r4,
r2, Operand::PointerOffsetFromSmiKey(
r3));
2385 __ LoadRoot(
ip, Heap::kMegamorphicSymbolRootIndex);
2390 __ bind(&initialize);
2392 if (!FLAG_pretenuring_call_new) {
2396 __ b(
ne, ¬_array_function);
2408 CreateAllocationSiteStub create_stub(masm->isolate());
2409 __ CallStub(&create_stub);
2416 __ bind(¬_array_function);
2419 __ add(
r4,
r2, Operand::PointerOffsetFromSmiKey(
r3));
2432 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
2446 static void EmitSlowCase(MacroAssembler* masm,
2448 Label* non_function) {
2451 __ b(
ne, non_function);
2454 __ mov(
r2, Operand::Zero());
2455 __ GetBuiltinFunction(
r1, Builtins::CALL_FUNCTION_PROXY);
2457 Handle<Code> adaptor =
2458 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
2464 __ bind(non_function);
2466 __ mov(
r0, Operand(argc));
2467 __ mov(
r2, Operand::Zero());
2468 __ GetBuiltinFunction(
r1, Builtins::CALL_NON_FUNCTION);
2469 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
2474 static void EmitWrapCase(MacroAssembler* masm,
int argc, Label* cont) {
2486 static void CallFunctionNoFeedback(MacroAssembler* masm,
2487 int argc,
bool needs_checks,
2488 bool call_as_method) {
2490 Label slow, non_function, wrap, cont;
2495 __ JumpIfSmi(
r1, &non_function);
2504 ParameterCount actual(argc);
2506 if (call_as_method) {
2508 EmitContinueIfStrictOrNative(masm, &cont);
2515 __ JumpIfSmi(
r3, &wrap);
2530 EmitSlowCase(masm, argc, &non_function);
2533 if (call_as_method) {
2535 EmitWrapCase(masm, argc, &cont);
2551 Label slow, non_function_call;
2554 __ JumpIfSmi(
r1, &non_function_call);
2560 GenerateRecordCallTarget(masm);
2562 __ add(
r5,
r2, Operand::PointerOffsetFromSmiKey(
r3));
2563 if (FLAG_pretenuring_call_new) {
2569 Label feedback_register_initialized;
2573 __ CompareRoot(
r5, Heap::kAllocationSiteMapRootIndex);
2574 __ b(
eq, &feedback_register_initialized);
2575 __ LoadRoot(
r2, Heap::kUndefinedValueRootIndex);
2576 __ bind(&feedback_register_initialized);
2579 __ AssertUndefinedOrAllocationSite(
r2,
r5);
2583 Register jmp_reg =
r4;
2595 __ b(
ne, &non_function_call);
2596 __ GetBuiltinFunction(
r1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
2599 __ bind(&non_function_call);
2600 __ GetBuiltinFunction(
r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
2603 __ mov(
r2, Operand::Zero());
2604 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
2609 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
2623 ParameterCount actual(argc);
2625 EmitLoadTypeFeedbackVector(masm,
r2);
2632 __ add(
r4,
r2, Operand::PointerOffsetFromSmiKey(
r3));
2637 __ CompareRoot(
r5, Heap::kAllocationSiteMapRootIndex);
2641 ArrayConstructorStub stub(masm->isolate(),
arg_count());
2642 __ TailCallStub(&stub);
2648 CallFunctionNoFeedback(masm,
2654 __ stop(
"Unexpected code address");
2661 Label extra_checks_or_miss, slow_start;
2662 Label slow, non_function, wrap, cont;
2663 Label have_js_function;
2665 ParameterCount actual(argc);
2667 EmitLoadTypeFeedbackVector(masm,
r2);
2670 __ add(
r4,
r2, Operand::PointerOffsetFromSmiKey(
r3));
2673 __ b(
ne, &extra_checks_or_miss);
2675 __ bind(&have_js_function);
2677 EmitContinueIfStrictOrNative(masm, &cont);
2681 __ JumpIfSmi(
r3, &wrap);
2691 EmitSlowCase(masm, argc, &non_function);
2695 EmitWrapCase(masm, argc, &cont);
2698 __ bind(&extra_checks_or_miss);
2701 __ CompareRoot(
r4, Heap::kMegamorphicSymbolRootIndex);
2702 __ b(
eq, &slow_start);
2703 __ CompareRoot(
r4, Heap::kUninitializedSymbolRootIndex);
2706 if (!FLAG_trace_ic) {
2709 __ AssertNotSmi(
r4);
2712 __ add(
r4,
r2, Operand::PointerOffsetFromSmiKey(
r3));
2713 __ LoadRoot(
ip, Heap::kMegamorphicSymbolRootIndex);
2715 __ jmp(&slow_start);
2723 __ bind(&slow_start);
2726 __ JumpIfSmi(
r1, &non_function);
2731 __ jmp(&have_js_function);
2747 : IC::kCallIC_Customization_Miss;
2749 ExternalReference miss = ExternalReference(IC_Utility(
id),
2751 __ CallExternalReference(miss, 4);
2794 MacroAssembler* masm,
2795 const RuntimeCallHelper& call_helper) {
2796 __ Abort(kUnexpectedFallthroughToCharCodeAtSlowCase);
2803 Heap::kHeapNumberMapRootIndex,
2806 call_helper.BeforeCall(masm);
2810 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
2814 __ CallRuntime(Runtime::kNumberToSmi, 1);
2823 call_helper.AfterCall(masm);
2833 call_helper.BeforeCall(masm);
2836 __ CallRuntime(Runtime::kStringCharCodeAtRT, 2);
2838 call_helper.AfterCall(masm);
2841 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase);
2858 __ LoadRoot(
result_, Heap::kSingleCharacterStringCacheRootIndex);
2862 __ CompareRoot(
result_, Heap::kUndefinedValueRootIndex);
2869 MacroAssembler* masm,
2870 const RuntimeCallHelper& call_helper) {
2871 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase);
2874 call_helper.BeforeCall(masm);
2876 __ CallRuntime(Runtime::kCharFromCode, 1);
2878 call_helper.AfterCall(masm);
2881 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase);
2885 enum CopyCharactersFlags { COPY_ONE_BYTE = 1, DEST_ALWAYS_ALIGNED = 2 };
2894 if (FLAG_debug_code) {
2897 __ Check(
eq, kDestinationOfCopyNotAligned);
2904 __ add(count, count, Operand(count),
SetCC);
2907 Register limit = count;
2908 __ add(limit, dest, Operand(count));
2910 Label loop_entry, loop;
2916 __ bind(&loop_entry);
2917 __ cmp(dest, Operand(limit));
2966 __ JumpIfSmi(
r0, &runtime);
2971 __ cmp(
r2, Operand(1));
2972 __ b(
eq, &single_char);
2981 __ b(
eq, &return_r0);
2992 Label underlying_unpacked, sliced_string, seq_or_external_string;
2997 __ b(
eq, &seq_or_external_string);
3000 __ b(
ne, &sliced_string);
3003 __ CompareRoot(
r5, Heap::kempty_stringRootIndex);
3009 __ jmp(&underlying_unpacked);
3011 __ bind(&sliced_string);
3019 __ jmp(&underlying_unpacked);
3021 __ bind(&seq_or_external_string);
3025 __ bind(&underlying_unpacked);
3027 if (FLAG_string_slices) {
3035 __ b(
lt, ©_routine);
3041 Label two_byte_slice, set_slice_header;
3045 __ b(
eq, &two_byte_slice);
3046 __ AllocateOneByteSlicedString(
r0,
r2,
r6,
r4, &runtime);
3047 __ jmp(&set_slice_header);
3048 __ bind(&two_byte_slice);
3049 __ AllocateTwoByteSlicedString(
r0,
r2,
r6,
r4, &runtime);
3050 __ bind(&set_slice_header);
3056 __ bind(©_routine);
3063 Label two_byte_sequential, sequential_string, allocate_result;
3067 __ b(
eq, &sequential_string);
3076 __ jmp(&allocate_result);
3078 __ bind(&sequential_string);
3083 __ bind(&allocate_result);
3087 __ b(
eq, &two_byte_sequential);
3090 __ AllocateOneByteString(
r0,
r2,
r4,
r6,
r1, &runtime);
3107 __ bind(&two_byte_sequential);
3108 __ AllocateTwoByteString(
r0,
r2,
r4,
r6,
r1, &runtime);
3124 __ bind(&return_r0);
3125 Counters* counters = isolate()->counters();
3126 __ IncrementCounter(counters->sub_string_native(), 1,
r3,
r4);
3132 __ TailCallRuntime(Runtime::kSubString, 3, 1);
3134 __ bind(&single_char);
3140 StringCharAtGenerator generator(
3142 generator.GenerateFast(masm);
3145 generator.SkipSlow(masm, &runtime);
3150 MacroAssembler* masm, Register left, Register right, Register scratch1,
3151 Register scratch2, Register scratch3) {
3152 Register length = scratch1;
3155 Label strings_not_equal, check_zero_length;
3158 __ cmp(length, scratch2);
3159 __ b(
eq, &check_zero_length);
3160 __ bind(&strings_not_equal);
3165 Label compare_chars;
3166 __ bind(&check_zero_length);
3168 __ cmp(length, Operand::Zero());
3169 __ b(
ne, &compare_chars);
3174 __ bind(&compare_chars);
3176 &strings_not_equal);
3185 MacroAssembler* masm, Register left, Register right, Register scratch1,
3186 Register scratch2, Register scratch3, Register scratch4) {
3187 Label result_not_equal, compare_lengths;
3191 __ sub(scratch3, scratch1, Operand(scratch2),
SetCC);
3192 Register length_delta = scratch3;
3194 Register min_length = scratch1;
3196 __ cmp(min_length, Operand::Zero());
3197 __ b(
eq, &compare_lengths);
3201 scratch4, &result_not_equal);
3204 __ bind(&compare_lengths);
3207 __ mov(
r0, Operand(length_delta),
SetCC);
3208 __ bind(&result_not_equal);
3218 MacroAssembler* masm, Register left, Register right, Register length,
3219 Register scratch1, Register scratch2, Label* chars_not_equal) {
3223 __ SmiUntag(length);
3224 __ add(scratch1, length,
3226 __ add(left, left, Operand(scratch1));
3227 __ add(right, right, Operand(scratch1));
3228 __ rsb(length, length, Operand::Zero());
3229 Register index = length;
3236 __ cmp(scratch1, scratch2);
3237 __ b(
ne, chars_not_equal);
3238 __ add(index, index, Operand(1),
SetCC);
3246 Counters* counters = isolate()->counters();
3255 __ b(
ne, ¬_same);
3259 __ IncrementCounter(counters->string_compare_native(), 1,
r1,
r2);
3266 __ JumpIfNotBothSequentialOneByteStrings(
r1,
r0,
r2,
r3, &runtime);
3269 __ IncrementCounter(counters->string_compare_native(), 1,
r2,
r3);
3276 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3280 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
3290 __ Move(
r2,
handle(isolate()->heap()->undefined_value()));
3293 if (FLAG_debug_code) {
3295 __ Assert(
ne, kExpectedAllocationSite);
3298 __ LoadRoot(
ip, Heap::kAllocationSiteMapRootIndex);
3301 __ Assert(
eq, kExpectedAllocationSite);
3306 BinaryOpWithAllocationSiteStub stub(isolate(), state());
3307 __ TailCallStub(&stub);
3315 __ JumpIfNotSmi(
r2, &miss);
3323 __ sub(
r0,
r1, Operand::SmiUntag(
r0));
3336 Label unordered, maybe_undefined1, maybe_undefined2;
3340 __ JumpIfNotSmi(
r1, &miss);
3343 __ JumpIfNotSmi(
r0, &miss);
3349 Label done,
left, left_smi, right_smi;
3350 __ JumpIfSmi(
r0, &right_smi);
3351 __ CheckMap(
r0,
r2, Heap::kHeapNumberMapRootIndex, &maybe_undefined1,
3356 __ bind(&right_smi);
3360 __ JumpIfSmi(
r1, &left_smi);
3361 __ CheckMap(
r1,
r2, Heap::kHeapNumberMapRootIndex, &maybe_undefined2,
3371 __ VFPCompareAndSetFlags(
d0,
d1);
3374 __ b(
vs, &unordered);
3382 __ bind(&unordered);
3383 __ bind(&generic_stub);
3388 __ bind(&maybe_undefined1);
3390 __ CompareRoot(
r0, Heap::kUndefinedValueRootIndex);
3392 __ JumpIfSmi(
r1, &unordered);
3394 __ b(
ne, &maybe_undefined2);
3398 __ bind(&maybe_undefined2);
3400 __ CompareRoot(
r1, Heap::kUndefinedValueRootIndex);
3401 __ b(
eq, &unordered);
3428 __ orr(tmp1, tmp1, Operand(tmp2));
3468 __ JumpIfNotUniqueNameInstanceType(tmp1, &miss);
3469 __ JumpIfNotUniqueNameInstanceType(tmp2, &miss);
3510 __ orr(tmp3, tmp1, tmp2);
3529 __ orr(tmp3, tmp1, Operand(tmp2));
3539 __ JumpIfBothInstanceTypesAreNotSequentialOneByte(tmp1, tmp2, tmp3, tmp4,
3555 __ TailCallRuntime(Runtime::kStringEquals, 2, 1);
3557 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3569 __ JumpIfSmi(
r2, &miss);
3588 __ JumpIfSmi(
r2, &miss);
3607 ExternalReference miss =
3608 ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate());
3615 __ CallExternalReference(miss, 3);
3632 __ VFPEnsureFPSCRState(
r2);
3640 reinterpret_cast<intptr_t
>(GetCode().location());
3641 __ Move(
ip, target);
3651 Register properties,
3653 Register scratch0) {
3663 Register
index = scratch0;
3674 Register entity_name = scratch0;
3677 Register tmp = properties;
3678 __ add(tmp, properties, Operand(
index,
LSL, 1));
3681 DCHECK(!tmp.is(entity_name));
3682 __ LoadRoot(tmp, Heap::kUndefinedValueRootIndex);
3683 __ cmp(entity_name, tmp);
3687 __ LoadRoot(tmp, Heap::kTheHoleValueRootIndex);
3690 __ cmp(entity_name, Operand(Handle<Name>(
name)));
3694 __ cmp(entity_name, tmp);
3699 __ ldrb(entity_name,
3701 __ JumpIfNotUniqueNameInstanceType(entity_name, miss);
3709 const int spill_mask =
3715 __ mov(
r1, Operand(Handle<Name>(
name)));
3718 __ cmp(
r0, Operand::Zero());
3736 Register scratch2) {
3737 DCHECK(!elements.is(scratch1));
3738 DCHECK(!elements.is(scratch2));
3746 __ SmiUntag(scratch1);
3747 __ sub(scratch1, scratch1, Operand(1));
3759 DCHECK(NameDictionary::GetProbeOffset(
i) <
3761 __ add(scratch2, scratch2, Operand(
3769 __ add(scratch2, scratch2, Operand(scratch2,
LSL, 1));
3772 __ add(scratch2, elements, Operand(scratch2,
LSL, 2));
3778 const int spill_mask =
3781 ~(scratch1.bit() | scratch2.bit());
3787 __ Move(
r0, elements);
3789 __ Move(
r0, elements);
3794 __ cmp(
r0, Operand::Zero());
3795 __ mov(scratch2, Operand(
r2));
3821 Register undefined =
r5;
3822 Register entry_key =
r6;
3824 Label in_dictionary, maybe_in_dictionary, not_in_dictionary;
3828 __ sub(mask, mask, Operand(1));
3832 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex);
3841 DCHECK(NameDictionary::GetProbeOffset(
i) <
3859 __ cmp(entry_key, Operand(undefined));
3860 __ b(
eq, ¬_in_dictionary);
3863 __ cmp(entry_key, Operand(key));
3864 __ b(
eq, &in_dictionary);
3871 __ JumpIfNotUniqueNameInstanceType(entry_key, &maybe_in_dictionary);
3875 __ bind(&maybe_in_dictionary);
3884 __ bind(&in_dictionary);
3888 __ bind(¬_in_dictionary);
3909 Label skip_to_incremental_noncompacting;
3910 Label skip_to_incremental_compacting;
3921 __ b(&skip_to_incremental_noncompacting);
3922 __ b(&skip_to_incremental_compacting);
3931 __ bind(&skip_to_incremental_noncompacting);
3934 __ bind(&skip_to_incremental_compacting);
3950 Label dont_need_remembered_set;
3955 &dont_need_remembered_set);
3961 &dont_need_remembered_set);
3972 __ bind(&dont_need_remembered_set);
3985 int argument_count = 3;
3994 __ mov(
r2, Operand(ExternalReference::isolate_address(isolate())));
3996 AllowExternalCallThatCantCauseGC scope(masm);
3998 ExternalReference::incremental_marking_record_write_function(isolate()),
4005 MacroAssembler* masm,
4006 OnNoNeedToInformIncrementalMarker on_no_need,
4009 Label need_incremental;
4010 Label need_incremental_pop_scratch;
4020 __ b(
mi, &need_incremental);
4040 Label ensure_not_white;
4054 __ bind(&ensure_not_white);
4064 &need_incremental_pop_scratch);
4075 __ bind(&need_incremental_pop_scratch);
4078 __ bind(&need_incremental);
4094 Label double_elements;
4096 Label slow_elements;
4097 Label fast_elements;
4104 __ CheckFastElements(
r2,
r5, &double_elements);
4106 __ JumpIfSmi(
r0, &smi_element);
4107 __ CheckFastSmiElements(
r2,
r5, &fast_elements);
4111 __ bind(&slow_elements);
4117 __ TailCallRuntime(Runtime::kStoreArrayLiteralElement, 5, 1);
4120 __ bind(&fast_elements);
4122 __ add(
r6,
r5, Operand::PointerOffsetFromSmiKey(
r3));
4132 __ bind(&smi_element);
4134 __ add(
r6,
r5, Operand::PointerOffsetFromSmiKey(
r3));
4139 __ bind(&double_elements);
4141 __ StoreNumberToDoubleElements(
r0,
r3,
r5,
r6,
d0, &slow_elements);
4149 int parameter_count_offset =
4153 __ add(
r1,
r1, Operand(1));
4155 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
4164 VectorLoadStub stub(isolate(),
state());
4171 VectorKeyedLoadStub stub(isolate());
4177 if (masm->isolate()->function_entry_hook() !=
NULL) {
4180 PredictableCodeSizeScope predictable(masm, code_size);
4190 const int32_t kReturnAddressDistanceFromFunctionStart =
4202 const int32_t kNumSavedRegs = 7;
4210 __ sub(
r0,
lr, Operand(kReturnAddressDistanceFromFunctionStart));
4217 int frame_alignment = masm->ActivationFrameAlignment();
4221 __ and_(
sp,
sp, Operand(-frame_alignment));
4224 #if V8_HOST_ARCH_ARM
4226 reinterpret_cast<int32_t>(isolate()->function_entry_hook());
4227 __ mov(
ip, Operand(entry_hook));
4232 __ mov(
r2, Operand(ExternalReference::isolate_address(isolate())));
4235 __ mov(
ip, Operand(ExternalReference(&dispatcher,
4236 ExternalReference::BUILTIN_CALL,
4252 static void CreateArrayDispatch(MacroAssembler* masm,
4256 __ TailCallStub(&stub);
4260 for (
int i = 0;
i <= last_index; ++
i) {
4262 __ cmp(
r3, Operand(kind));
4263 T stub(masm->isolate(), kind);
4264 __ TailCallStub(&stub,
eq);
4268 __ Abort(kUnexpectedElementsKindInArrayConstructor);
4275 static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
4282 Label normal_sequence;
4292 __ tst(
r3, Operand(1));
4293 __ b(
ne, &normal_sequence);
4298 __ cmp(
r5, Operand::Zero());
4299 __ b(
eq, &normal_sequence);
4305 ArraySingleArgumentConstructorStub stub_holey(masm->isolate(),
4308 __ TailCallStub(&stub_holey);
4310 __ bind(&normal_sequence);
4311 ArraySingleArgumentConstructorStub stub(masm->isolate(),
4314 __ TailCallStub(&stub);
4318 __ add(
r3,
r3, Operand(1));
4320 if (FLAG_debug_code) {
4322 __ CompareRoot(
r5, Heap::kAllocationSiteMapRootIndex);
4323 __ Assert(
eq, kExpectedAllocationSite);
4334 __ bind(&normal_sequence);
4337 for (
int i = 0;
i <= last_index; ++
i) {
4339 __ cmp(
r3, Operand(kind));
4340 ArraySingleArgumentConstructorStub stub(masm->isolate(), kind);
4341 __ TailCallStub(&stub,
eq);
4345 __ Abort(kUnexpectedElementsKindInArrayConstructor);
4353 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
4356 for (
int i = 0;
i <= to_index; ++
i) {
4358 T stub(isolate, kind);
4369 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
4371 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
4373 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
4381 for (
int i = 0;
i < 2;
i++) {
4383 InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[
i]);
4385 InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[
i]);
4387 InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[
i]);
4394 MacroAssembler* masm,
4397 Label not_zero_case, not_one_case;
4399 __ b(
ne, ¬_zero_case);
4400 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm,
mode);
4402 __ bind(¬_zero_case);
4403 __ cmp(
r0, Operand(1));
4404 __ b(
gt, ¬_one_case);
4405 CreateArrayDispatchOneArgument(masm,
mode);
4407 __ bind(¬_one_case);
4408 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm,
mode);
4410 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm,
mode);
4412 CreateArrayDispatchOneArgument(masm,
mode);
4414 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm,
mode);
4430 if (FLAG_debug_code) {
4438 __ Assert(
ne, kUnexpectedInitialMapForArrayFunction);
4440 __ Assert(
eq, kUnexpectedInitialMapForArrayFunction);
4443 __ AssertUndefinedOrAllocationSite(
r2,
r4);
4448 __ CompareRoot(
r2, Heap::kUndefinedValueRootIndex);
4464 __ cmp(
r0, Operand(1));
4466 InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
4467 __ TailCallStub(&stub0,
lo);
4469 InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
4470 __ TailCallStub(&stubN,
hi);
4476 __ cmp(
r3, Operand::Zero());
4478 InternalArraySingleArgumentConstructorStub
4480 __ TailCallStub(&stub1_holey,
ne);
4483 InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
4484 __ TailCallStub(&stub1);
4496 if (FLAG_debug_code) {
4504 __ Assert(
ne, kUnexpectedInitialMapForArrayFunction);
4506 __ Assert(
eq, kUnexpectedInitialMapForArrayFunction);
4515 __ DecodeField<Map::ElementsKindBits>(
r3);
4517 if (FLAG_debug_code) {
4523 kInvalidElementsKindForInternalArrayOrInternalPackedArray);
4527 Label fast_elements_case;
4529 __ b(
eq, &fast_elements_case);
4532 __ bind(&fast_elements_case);
4551 Register callee =
r0;
4552 Register call_data =
r4;
4553 Register holder =
r2;
4554 Register api_function_address =
r1;
4555 Register context =
cp;
4561 typedef FunctionCallbackArguments FCA;
4583 Register scratch = call_data;
4585 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
4593 Operand(ExternalReference::isolate_address(isolate())));
4599 __ mov(scratch,
sp);
4603 const int kApiStackSpace = 4;
4605 FrameScope frame_scope(masm, StackFrame::MANUAL);
4606 __ EnterExitFrame(
false, kApiStackSpace);
4608 DCHECK(!api_function_address.is(
r0) && !scratch.is(
r0));
4621 __ mov(
ip, Operand::Zero());
4624 const int kStackUnwindSpace =
argc + FCA::kArgsLength + 1;
4625 ExternalReference thunk_ref =
4626 ExternalReference::invoke_function_callback(isolate());
4628 AllowExternalCallThatCantCauseGC scope(masm);
4632 int return_value_offset = 0;
4634 return_value_offset = 2 + FCA::kArgsLength;
4636 return_value_offset = 2 + FCA::kReturnValueOffset;
4640 __ CallApiFunctionAndReturn(api_function_address,
4643 return_value_operand,
4644 &context_restore_operand);
4657 DCHECK(api_function_address.is(
r2));
4662 const int kApiStackSpace = 1;
4663 FrameScope frame_scope(masm, StackFrame::MANUAL);
4664 __ EnterExitFrame(
false, kApiStackSpace);
4673 ExternalReference thunk_ref =
4674 ExternalReference::invoke_accessor_getter_callback(isolate());
4675 __ CallApiFunctionAndReturn(api_function_address,
#define kFirstCalleeSavedDoubleReg
#define kScratchDoubleReg
#define kLastCalleeSavedDoubleReg
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 kInstrSize
friend class BlockConstPoolScope
static int GetBranchOffset(Instr instr)
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 kValueOffset
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 void GenerateAheadOfTime(Isolate *isolate)
void GenerateCall(MacroAssembler *masm, Register target)
bool skip_fastpath() const
bool is_truncating() const
STATIC_ASSERT((1L<< kBitsPerRegisterNumber) >=Register::kNumRegisters)
Register destination() const
static const int kCallerFPOffset
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 uint32_t kSignMask
static const int kValueOffset
static const int kMantissaBitsInTopWord
static const int kExponentBits
static const int kExponentBias
static const int kExponentShift
static const int kNonMantissaBitsInTopWord
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 int ActivationFrameAlignment()
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 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 void EntryHookTrampoline(intptr_t function, intptr_t stack_pointer, Isolate *isolate)
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
static void PatchBranchIntoNop(MacroAssembler *masm, int pos)
SaveFPRegsMode save_fp_regs_mode() const
@ kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
@ kReturnOnNoNeedToInformIncrementalMarker
void CheckNeedsToInformIncrementalMarker(MacroAssembler *masm, OnNoNeedToInformIncrementalMarker on_no_need, Mode mode)
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 kCompilerHintsOffset
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()
void Generate(MacroAssembler *masm)
Register the_heap_number() const
static void GenerateFixedRegStubsAheadOfTime(Isolate *isolate)
WriteInt32ToHeapNumberStub(Isolate *isolate, Register the_int, Register the_heap_number, Register scratch)
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)
static int Push(SpecialRPOStackFrame *stack, int depth, BasicBlock *child, int unvisited)
const LowDwVfpRegister d2
const uint32_t kStringEncodingMask
const LowDwVfpRegister d7
ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number)
@ DONT_TRACK_ALLOCATION_SITE
const LowDwVfpRegister d6
const intptr_t kPointerAlignmentMask
const LowDwVfpRegister d1
const uint32_t kTwoByteStringTag
const uint32_t kShortExternalStringTag
const RegList kCalleeSaved
const LowDwVfpRegister d0
const int kFastElementsKindPackedToHoley
const uint32_t kNotStringTag
const int kPointerSizeLog2
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
MemOperand FieldMemOperand(Register object, int offset)
const intptr_t kObjectAlignmentMask
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)
const uint32_t kStringRepresentationMask
const uint32_t kSlicedNotConsMask
const uint32_t kInternalizedTag
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
const intptr_t kSmiTagMask
const uint32_t kIsNotInternalizedMask
Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2=no_reg, Register reg3=no_reg, Register reg4=no_reg, Register reg5=no_reg, Register reg6=no_reg)
const LowDwVfpRegister d3
const uint32_t kIsNotStringMask
const int kNumCalleeSaved
const int kNumDoubleCalleeSaved
ElementsKind GetInitialFastElementsKind()
@ STRING_INDEX_IS_ARRAY_INDEX
const uint32_t kIsIndirectStringMask
const RegList kCallerSaved
Debugger support for the V8 JavaScript engine.
static Handle< Value > Throw(Isolate *isolate, const char *message)
bool is(Register reg) const
#define T(name, string, precedence)