Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(687)

Side by Side Diff: src/arm/macro-assembler-arm.cc

Issue 110573004: Merge bleeding_edge 17696:18016. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; 613 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters;
614 ldm(ia_w, sp, kSafepointSavedRegisters); 614 ldm(ia_w, sp, kSafepointSavedRegisters);
615 add(sp, sp, Operand(num_unsaved * kPointerSize)); 615 add(sp, sp, Operand(num_unsaved * kPointerSize));
616 } 616 }
617 617
618 618
619 void MacroAssembler::PushSafepointRegistersAndDoubles() { 619 void MacroAssembler::PushSafepointRegistersAndDoubles() {
620 // Number of d-regs not known at snapshot time. 620 // Number of d-regs not known at snapshot time.
621 ASSERT(!Serializer::enabled()); 621 ASSERT(!Serializer::enabled());
622 PushSafepointRegisters(); 622 PushSafepointRegisters();
623 sub(sp, sp, Operand(DwVfpRegister::NumAllocatableRegisters() * 623 // Only save allocatable registers.
624 kDoubleSize)); 624 ASSERT(kScratchDoubleReg.is(d15) && kDoubleRegZero.is(d14));
625 for (int i = 0; i < DwVfpRegister::NumAllocatableRegisters(); i++) { 625 ASSERT(DwVfpRegister::NumReservedRegisters() == 2);
626 vstr(DwVfpRegister::FromAllocationIndex(i), sp, i * kDoubleSize); 626 if (CpuFeatures::IsSupported(VFP32DREGS)) {
627 vstm(db_w, sp, d16, d31);
627 } 628 }
629 vstm(db_w, sp, d0, d13);
628 } 630 }
629 631
630 632
631 void MacroAssembler::PopSafepointRegistersAndDoubles() { 633 void MacroAssembler::PopSafepointRegistersAndDoubles() {
632 // Number of d-regs not known at snapshot time. 634 // Number of d-regs not known at snapshot time.
633 ASSERT(!Serializer::enabled()); 635 ASSERT(!Serializer::enabled());
634 for (int i = 0; i < DwVfpRegister::NumAllocatableRegisters(); i++) { 636 // Only save allocatable registers.
635 vldr(DwVfpRegister::FromAllocationIndex(i), sp, i * kDoubleSize); 637 ASSERT(kScratchDoubleReg.is(d15) && kDoubleRegZero.is(d14));
638 ASSERT(DwVfpRegister::NumReservedRegisters() == 2);
639 vldm(ia_w, sp, d0, d13);
640 if (CpuFeatures::IsSupported(VFP32DREGS)) {
641 vldm(ia_w, sp, d16, d31);
636 } 642 }
637 add(sp, sp, Operand(DwVfpRegister::NumAllocatableRegisters() *
638 kDoubleSize));
639 PopSafepointRegisters(); 643 PopSafepointRegisters();
640 } 644 }
641 645
642 void MacroAssembler::StoreToSafepointRegistersAndDoublesSlot(Register src, 646 void MacroAssembler::StoreToSafepointRegistersAndDoublesSlot(Register src,
643 Register dst) { 647 Register dst) {
644 str(src, SafepointRegistersAndDoublesSlot(dst)); 648 str(src, SafepointRegistersAndDoublesSlot(dst));
645 } 649 }
646 650
647 651
648 void MacroAssembler::StoreToSafepointRegisterSlot(Register src, Register dst) { 652 void MacroAssembler::StoreToSafepointRegisterSlot(Register src, Register dst) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) { 855 void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) {
852 if (dst.code() < 16) { 856 if (dst.code() < 16) {
853 const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code()); 857 const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code());
854 vmov(loc.low(), src); 858 vmov(loc.low(), src);
855 } else { 859 } else {
856 vmov(dst, VmovIndexLo, src); 860 vmov(dst, VmovIndexLo, src);
857 } 861 }
858 } 862 }
859 863
860 864
861 void MacroAssembler::LoadNumber(Register object,
862 LowDwVfpRegister dst,
863 Register heap_number_map,
864 Register scratch,
865 Label* not_number) {
866 Label is_smi, done;
867
868 UntagAndJumpIfSmi(scratch, object, &is_smi);
869 JumpIfNotHeapNumber(object, heap_number_map, scratch, not_number);
870
871 vldr(dst, FieldMemOperand(object, HeapNumber::kValueOffset));
872 b(&done);
873
874 // Handle loading a double from a smi.
875 bind(&is_smi);
876 vmov(dst.high(), scratch);
877 vcvt_f64_s32(dst, dst.high());
878
879 bind(&done);
880 }
881
882
883 void MacroAssembler::LoadNumberAsInt32Double(Register object,
884 DwVfpRegister double_dst,
885 Register heap_number_map,
886 Register scratch,
887 LowDwVfpRegister double_scratch,
888 Label* not_int32) {
889 ASSERT(!scratch.is(object));
890 ASSERT(!heap_number_map.is(object) && !heap_number_map.is(scratch));
891
892 Label done, obj_is_not_smi;
893
894 UntagAndJumpIfNotSmi(scratch, object, &obj_is_not_smi);
895 vmov(double_scratch.low(), scratch);
896 vcvt_f64_s32(double_dst, double_scratch.low());
897 b(&done);
898
899 bind(&obj_is_not_smi);
900 JumpIfNotHeapNumber(object, heap_number_map, scratch, not_int32);
901
902 // Load the number.
903 // Load the double value.
904 vldr(double_dst, FieldMemOperand(object, HeapNumber::kValueOffset));
905
906 TestDoubleIsInt32(double_dst, double_scratch);
907 // Jump to not_int32 if the operation did not succeed.
908 b(ne, not_int32);
909
910 bind(&done);
911 }
912
913
914 void MacroAssembler::LoadNumberAsInt32(Register object,
915 Register dst,
916 Register heap_number_map,
917 Register scratch,
918 DwVfpRegister double_scratch0,
919 LowDwVfpRegister double_scratch1,
920 Label* not_int32) {
921 ASSERT(!dst.is(object));
922 ASSERT(!scratch.is(object));
923
924 Label done, maybe_undefined;
925
926 UntagAndJumpIfSmi(dst, object, &done);
927
928 JumpIfNotHeapNumber(object, heap_number_map, scratch, &maybe_undefined);
929
930 // Object is a heap number.
931 // Convert the floating point value to a 32-bit integer.
932 // Load the double value.
933 vldr(double_scratch0, FieldMemOperand(object, HeapNumber::kValueOffset));
934
935 TryDoubleToInt32Exact(dst, double_scratch0, double_scratch1);
936 // Jump to not_int32 if the operation did not succeed.
937 b(ne, not_int32);
938 b(&done);
939
940 bind(&maybe_undefined);
941 CompareRoot(object, Heap::kUndefinedValueRootIndex);
942 b(ne, not_int32);
943 // |undefined| is truncated to 0.
944 mov(dst, Operand(Smi::FromInt(0)));
945 // Fall through.
946
947 bind(&done);
948 }
949
950
951 void MacroAssembler::Prologue(PrologueFrameMode frame_mode) { 865 void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
952 if (frame_mode == BUILD_STUB_FRAME) { 866 if (frame_mode == BUILD_STUB_FRAME) {
953 stm(db_w, sp, cp.bit() | fp.bit() | lr.bit()); 867 stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
954 Push(Smi::FromInt(StackFrame::STUB)); 868 Push(Smi::FromInt(StackFrame::STUB));
955 // Adjust FP to point to saved FP. 869 // Adjust FP to point to saved FP.
956 add(fp, sp, Operand(2 * kPointerSize)); 870 add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
957 } else { 871 } else {
958 PredictableCodeSizeScope predictible_code_size_scope( 872 PredictableCodeSizeScope predictible_code_size_scope(
959 this, kNoCodeAgeSequenceLength * Assembler::kInstrSize); 873 this, kNoCodeAgeSequenceLength * Assembler::kInstrSize);
960 // The following three instructions must remain together and unmodified 874 // The following three instructions must remain together and unmodified
961 // for code aging to work properly. 875 // for code aging to work properly.
962 if (isolate()->IsCodePreAgingActive()) { 876 if (isolate()->IsCodePreAgingActive()) {
963 // Pre-age the code. 877 // Pre-age the code.
964 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); 878 Code* stub = Code::GetPreAgedCodeAgeStub(isolate());
965 add(r0, pc, Operand(-8)); 879 add(r0, pc, Operand(-8));
966 ldr(pc, MemOperand(pc, -4)); 880 ldr(pc, MemOperand(pc, -4));
967 emit_code_stub_address(stub); 881 emit_code_stub_address(stub);
968 } else { 882 } else {
969 stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); 883 stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
970 nop(ip.code()); 884 nop(ip.code());
971 // Adjust FP to point to saved FP. 885 // Adjust FP to point to saved FP.
972 add(fp, sp, Operand(2 * kPointerSize)); 886 add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
973 } 887 }
974 } 888 }
975 } 889 }
976 890
977 891
978 void MacroAssembler::EnterFrame(StackFrame::Type type) { 892 void MacroAssembler::EnterFrame(StackFrame::Type type) {
979 // r0-r3: preserved 893 // r0-r3: preserved
980 stm(db_w, sp, cp.bit() | fp.bit() | lr.bit()); 894 stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
981 mov(ip, Operand(Smi::FromInt(type))); 895 mov(ip, Operand(Smi::FromInt(type)));
982 push(ip); 896 push(ip);
983 mov(ip, Operand(CodeObject())); 897 mov(ip, Operand(CodeObject()));
984 push(ip); 898 push(ip);
985 add(fp, sp, Operand(3 * kPointerSize)); // Adjust FP to point to saved FP. 899 // Adjust FP to point to saved FP.
900 add(fp, sp,
901 Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize));
986 } 902 }
987 903
988 904
989 void MacroAssembler::LeaveFrame(StackFrame::Type type) { 905 void MacroAssembler::LeaveFrame(StackFrame::Type type) {
990 // r0: preserved 906 // r0: preserved
991 // r1: preserved 907 // r1: preserved
992 // r2: preserved 908 // r2: preserved
993 909
994 // Drop the execution stack down to the frame pointer and restore 910 // Drop the execution stack down to the frame pointer and restore
995 // the caller frame pointer and return address. 911 // the caller frame pointer and return address.
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 1499
1584 ldr(scratch, FieldMemOperand(scratch, token_offset)); 1500 ldr(scratch, FieldMemOperand(scratch, token_offset));
1585 ldr(ip, FieldMemOperand(ip, token_offset)); 1501 ldr(ip, FieldMemOperand(ip, token_offset));
1586 cmp(scratch, Operand(ip)); 1502 cmp(scratch, Operand(ip));
1587 b(ne, miss); 1503 b(ne, miss);
1588 1504
1589 bind(&same_contexts); 1505 bind(&same_contexts);
1590 } 1506 }
1591 1507
1592 1508
1509 // Compute the hash code from the untagged key. This must be kept in sync with
1510 // ComputeIntegerHash in utils.h and KeyedLoadGenericElementStub in
1511 // code-stub-hydrogen.cc
1593 void MacroAssembler::GetNumberHash(Register t0, Register scratch) { 1512 void MacroAssembler::GetNumberHash(Register t0, Register scratch) {
1594 // First of all we assign the hash seed to scratch. 1513 // First of all we assign the hash seed to scratch.
1595 LoadRoot(scratch, Heap::kHashSeedRootIndex); 1514 LoadRoot(scratch, Heap::kHashSeedRootIndex);
1596 SmiUntag(scratch); 1515 SmiUntag(scratch);
1597 1516
1598 // Xor original key with a seed. 1517 // Xor original key with a seed.
1599 eor(t0, t0, Operand(scratch)); 1518 eor(t0, t0, Operand(scratch));
1600 1519
1601 // Compute the hash code from the untagged key. This must be kept in sync 1520 // Compute the hash code from the untagged key. This must be kept in sync
1602 // with ComputeIntegerHash in utils.h. 1521 // with ComputeIntegerHash in utils.h.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1649 Label done; 1568 Label done;
1650 1569
1651 GetNumberHash(t0, t1); 1570 GetNumberHash(t0, t1);
1652 1571
1653 // Compute the capacity mask. 1572 // Compute the capacity mask.
1654 ldr(t1, FieldMemOperand(elements, SeededNumberDictionary::kCapacityOffset)); 1573 ldr(t1, FieldMemOperand(elements, SeededNumberDictionary::kCapacityOffset));
1655 SmiUntag(t1); 1574 SmiUntag(t1);
1656 sub(t1, t1, Operand(1)); 1575 sub(t1, t1, Operand(1));
1657 1576
1658 // Generate an unrolled loop that performs a few probes before giving up. 1577 // Generate an unrolled loop that performs a few probes before giving up.
1659 static const int kProbes = 4; 1578 for (int i = 0; i < kNumberDictionaryProbes; i++) {
1660 for (int i = 0; i < kProbes; i++) {
1661 // Use t2 for index calculations and keep the hash intact in t0. 1579 // Use t2 for index calculations and keep the hash intact in t0.
1662 mov(t2, t0); 1580 mov(t2, t0);
1663 // Compute the masked index: (hash + i + i * i) & mask. 1581 // Compute the masked index: (hash + i + i * i) & mask.
1664 if (i > 0) { 1582 if (i > 0) {
1665 add(t2, t2, Operand(SeededNumberDictionary::GetProbeOffset(i))); 1583 add(t2, t2, Operand(SeededNumberDictionary::GetProbeOffset(i)));
1666 } 1584 }
1667 and_(t2, t2, Operand(t1)); 1585 and_(t2, t2, Operand(t1));
1668 1586
1669 // Scale the index by multiplying by the element size. 1587 // Scale the index by multiplying by the element size.
1670 ASSERT(SeededNumberDictionary::kEntrySize == 3); 1588 ASSERT(SeededNumberDictionary::kEntrySize == 3);
1671 add(t2, t2, Operand(t2, LSL, 1)); // t2 = t2 * 3 1589 add(t2, t2, Operand(t2, LSL, 1)); // t2 = t2 * 3
1672 1590
1673 // Check if the key is identical to the name. 1591 // Check if the key is identical to the name.
1674 add(t2, elements, Operand(t2, LSL, kPointerSizeLog2)); 1592 add(t2, elements, Operand(t2, LSL, kPointerSizeLog2));
1675 ldr(ip, FieldMemOperand(t2, SeededNumberDictionary::kElementsStartOffset)); 1593 ldr(ip, FieldMemOperand(t2, SeededNumberDictionary::kElementsStartOffset));
1676 cmp(key, Operand(ip)); 1594 cmp(key, Operand(ip));
1677 if (i != kProbes - 1) { 1595 if (i != kNumberDictionaryProbes - 1) {
1678 b(eq, &done); 1596 b(eq, &done);
1679 } else { 1597 } else {
1680 b(ne, miss); 1598 b(ne, miss);
1681 } 1599 }
1682 } 1600 }
1683 1601
1684 bind(&done); 1602 bind(&done);
1685 // Check that the value is a normal property. 1603 // Check that the value is a normal property.
1686 // t2: elements + (index * kPointerSize) 1604 // t2: elements + (index * kPointerSize)
1687 const int kDetailsOffset = 1605 const int kDetailsOffset =
(...skipping 1780 matching lines...) Expand 10 before | Expand all | Expand 10 after
3468 num_reg_arguments += 2 * num_double_arguments; 3386 num_reg_arguments += 2 * num_double_arguments;
3469 } 3387 }
3470 // Up to four simple arguments are passed in registers r0..r3. 3388 // Up to four simple arguments are passed in registers r0..r3.
3471 if (num_reg_arguments > kRegisterPassedArguments) { 3389 if (num_reg_arguments > kRegisterPassedArguments) {
3472 stack_passed_words += num_reg_arguments - kRegisterPassedArguments; 3390 stack_passed_words += num_reg_arguments - kRegisterPassedArguments;
3473 } 3391 }
3474 return stack_passed_words; 3392 return stack_passed_words;
3475 } 3393 }
3476 3394
3477 3395
3396 void MacroAssembler::EmitSeqStringSetCharCheck(Register string,
3397 Register index,
3398 Register value,
3399 uint32_t encoding_mask) {
3400 Label is_object;
3401 SmiTst(string);
3402 ThrowIf(eq, kNonObject);
3403
3404 ldr(ip, FieldMemOperand(string, HeapObject::kMapOffset));
3405 ldrb(ip, FieldMemOperand(ip, Map::kInstanceTypeOffset));
3406
3407 and_(ip, ip, Operand(kStringRepresentationMask | kStringEncodingMask));
3408 cmp(ip, Operand(encoding_mask));
3409 ThrowIf(ne, kUnexpectedStringType);
3410
3411 // The index is assumed to be untagged coming in, tag it to compare with the
3412 // string length without using a temp register, it is restored at the end of
3413 // this function.
3414 Label index_tag_ok, index_tag_bad;
3415 TrySmiTag(index, index, &index_tag_bad);
3416 b(&index_tag_ok);
3417 bind(&index_tag_bad);
3418 Throw(kIndexIsTooLarge);
3419 bind(&index_tag_ok);
3420
3421 ldr(ip, FieldMemOperand(string, String::kLengthOffset));
3422 cmp(index, ip);
3423 ThrowIf(ge, kIndexIsTooLarge);
3424
3425 cmp(index, Operand(Smi::FromInt(0)));
3426 ThrowIf(lt, kIndexIsNegative);
3427
3428 SmiUntag(index, index);
3429 }
3430
3431
3478 void MacroAssembler::PrepareCallCFunction(int num_reg_arguments, 3432 void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
3479 int num_double_arguments, 3433 int num_double_arguments,
3480 Register scratch) { 3434 Register scratch) {
3481 int frame_alignment = ActivationFrameAlignment(); 3435 int frame_alignment = ActivationFrameAlignment();
3482 int stack_passed_arguments = CalculateStackPassedWords( 3436 int stack_passed_arguments = CalculateStackPassedWords(
3483 num_reg_arguments, num_double_arguments); 3437 num_reg_arguments, num_double_arguments);
3484 if (frame_alignment > kPointerSize) { 3438 if (frame_alignment > kPointerSize) {
3485 // Make stack end at alignment and make room for num_arguments - 4 words 3439 // Make stack end at alignment and make room for num_arguments - 4 words
3486 // and the original value of sp. 3440 // and the original value of sp.
3487 mov(scratch, sp); 3441 mov(scratch, sp);
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
3851 bic(result_reg, ip, Operand(kVFPRoundingModeMask)); 3805 bic(result_reg, ip, Operand(kVFPRoundingModeMask));
3852 vmsr(result_reg); 3806 vmsr(result_reg);
3853 vcvt_s32_f64(double_scratch.low(), input_reg, kFPSCRRounding); 3807 vcvt_s32_f64(double_scratch.low(), input_reg, kFPSCRRounding);
3854 vmov(result_reg, double_scratch.low()); 3808 vmov(result_reg, double_scratch.low());
3855 // Restore FPSCR. 3809 // Restore FPSCR.
3856 vmsr(ip); 3810 vmsr(ip);
3857 bind(&done); 3811 bind(&done);
3858 } 3812 }
3859 3813
3860 3814
3815 void MacroAssembler::Throw(BailoutReason reason) {
3816 Label throw_start;
3817 bind(&throw_start);
3818 #ifdef DEBUG
3819 const char* msg = GetBailoutReason(reason);
3820 if (msg != NULL) {
3821 RecordComment("Throw message: ");
3822 RecordComment(msg);
3823 }
3824 #endif
3825
3826 mov(r0, Operand(Smi::FromInt(reason)));
3827 push(r0);
3828 // Disable stub call restrictions to always allow calls to throw.
3829 if (!has_frame_) {
3830 // We don't actually want to generate a pile of code for this, so just
3831 // claim there is a stack frame, without generating one.
3832 FrameScope scope(this, StackFrame::NONE);
3833 CallRuntime(Runtime::kThrowMessage, 1);
3834 } else {
3835 CallRuntime(Runtime::kThrowMessage, 1);
3836 }
3837 // will not return here
3838 if (is_const_pool_blocked()) {
3839 // If the calling code cares throw the exact number of
3840 // instructions generated, we insert padding here to keep the size
3841 // of the ThrowMessage macro constant.
3842 static const int kExpectedThrowMessageInstructions = 10;
3843 int throw_instructions = InstructionsGeneratedSince(&throw_start);
3844 ASSERT(throw_instructions <= kExpectedThrowMessageInstructions);
3845 while (throw_instructions++ < kExpectedThrowMessageInstructions) {
3846 nop();
3847 }
3848 }
3849 }
3850
3851
3852 void MacroAssembler::ThrowIf(Condition cc, BailoutReason reason) {
3853 Label L;
3854 b(NegateCondition(cc), &L);
3855 Throw(reason);
3856 // will not return here
3857 bind(&L);
3858 }
3859
3860
3861 void MacroAssembler::LoadInstanceDescriptors(Register map, 3861 void MacroAssembler::LoadInstanceDescriptors(Register map,
3862 Register descriptors) { 3862 Register descriptors) {
3863 ldr(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset)); 3863 ldr(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset));
3864 } 3864 }
3865 3865
3866 3866
3867 void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { 3867 void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) {
3868 ldr(dst, FieldMemOperand(map, Map::kBitField3Offset)); 3868 ldr(dst, FieldMemOperand(map, Map::kBitField3Offset));
3869 DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); 3869 DecodeField<Map::NumberOfOwnDescriptorsBits>(dst);
3870 } 3870 }
(...skipping 10 matching lines...) Expand all
3881 Register empty_fixed_array_value = r6; 3881 Register empty_fixed_array_value = r6;
3882 LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); 3882 LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
3883 Label next, start; 3883 Label next, start;
3884 mov(r2, r0); 3884 mov(r2, r0);
3885 3885
3886 // Check if the enum length field is properly initialized, indicating that 3886 // Check if the enum length field is properly initialized, indicating that
3887 // there is an enum cache. 3887 // there is an enum cache.
3888 ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset)); 3888 ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset));
3889 3889
3890 EnumLength(r3, r1); 3890 EnumLength(r3, r1);
3891 cmp(r3, Operand(Smi::FromInt(Map::kInvalidEnumCache))); 3891 cmp(r3, Operand(Smi::FromInt(kInvalidEnumCacheSentinel)));
3892 b(eq, call_runtime); 3892 b(eq, call_runtime);
3893 3893
3894 jmp(&start); 3894 jmp(&start);
3895 3895
3896 bind(&next); 3896 bind(&next);
3897 ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset)); 3897 ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset));
3898 3898
3899 // For all objects but the receiver, check that the cache is empty. 3899 // For all objects but the receiver, check that the cache is empty.
3900 EnumLength(r3, r1); 3900 EnumLength(r3, r1);
3901 cmp(r3, Operand(Smi::FromInt(0))); 3901 cmp(r3, Operand(Smi::FromInt(0)));
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
4050 void CodePatcher::EmitCondition(Condition cond) { 4050 void CodePatcher::EmitCondition(Condition cond) {
4051 Instr instr = Assembler::instr_at(masm_.pc_); 4051 Instr instr = Assembler::instr_at(masm_.pc_);
4052 instr = (instr & ~kCondMask) | cond; 4052 instr = (instr & ~kCondMask) | cond;
4053 masm_.emit(instr); 4053 masm_.emit(instr);
4054 } 4054 }
4055 4055
4056 4056
4057 } } // namespace v8::internal 4057 } } // namespace v8::internal
4058 4058
4059 #endif // V8_TARGET_ARCH_ARM 4059 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698