| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 movq(dst, reinterpret_cast<uint64_t>(source), RelocInfo::NONE); | 986 movq(dst, reinterpret_cast<uint64_t>(source), RelocInfo::NONE); |
| 987 return; | 987 return; |
| 988 } | 988 } |
| 989 if (negative) { | 989 if (negative) { |
| 990 neg(dst); | 990 neg(dst); |
| 991 } | 991 } |
| 992 } | 992 } |
| 993 | 993 |
| 994 | 994 |
| 995 void MacroAssembler::Integer32ToSmi(Register dst, Register src) { | 995 void MacroAssembler::Integer32ToSmi(Register dst, Register src) { |
| 996 ASSERT_EQ(0, kSmiTag); | 996 STATIC_ASSERT(kSmiTag == 0); |
| 997 if (!dst.is(src)) { | 997 if (!dst.is(src)) { |
| 998 movl(dst, src); | 998 movl(dst, src); |
| 999 } | 999 } |
| 1000 shl(dst, Immediate(kSmiShift)); | 1000 shl(dst, Immediate(kSmiShift)); |
| 1001 } | 1001 } |
| 1002 | 1002 |
| 1003 | 1003 |
| 1004 void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) { | 1004 void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) { |
| 1005 if (emit_debug_code()) { | 1005 if (emit_debug_code()) { |
| 1006 testb(dst, Immediate(0x01)); | 1006 testb(dst, Immediate(0x01)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1024 if (dst.is(src)) { | 1024 if (dst.is(src)) { |
| 1025 addl(dst, Immediate(constant)); | 1025 addl(dst, Immediate(constant)); |
| 1026 } else { | 1026 } else { |
| 1027 leal(dst, Operand(src, constant)); | 1027 leal(dst, Operand(src, constant)); |
| 1028 } | 1028 } |
| 1029 shl(dst, Immediate(kSmiShift)); | 1029 shl(dst, Immediate(kSmiShift)); |
| 1030 } | 1030 } |
| 1031 | 1031 |
| 1032 | 1032 |
| 1033 void MacroAssembler::SmiToInteger32(Register dst, Register src) { | 1033 void MacroAssembler::SmiToInteger32(Register dst, Register src) { |
| 1034 ASSERT_EQ(0, kSmiTag); | 1034 STATIC_ASSERT(kSmiTag == 0); |
| 1035 if (!dst.is(src)) { | 1035 if (!dst.is(src)) { |
| 1036 movq(dst, src); | 1036 movq(dst, src); |
| 1037 } | 1037 } |
| 1038 shr(dst, Immediate(kSmiShift)); | 1038 shr(dst, Immediate(kSmiShift)); |
| 1039 } | 1039 } |
| 1040 | 1040 |
| 1041 | 1041 |
| 1042 void MacroAssembler::SmiToInteger32(Register dst, const Operand& src) { | 1042 void MacroAssembler::SmiToInteger32(Register dst, const Operand& src) { |
| 1043 movl(dst, Operand(src, kSmiShift / kBitsPerByte)); | 1043 movl(dst, Operand(src, kSmiShift / kBitsPerByte)); |
| 1044 } | 1044 } |
| 1045 | 1045 |
| 1046 | 1046 |
| 1047 void MacroAssembler::SmiToInteger64(Register dst, Register src) { | 1047 void MacroAssembler::SmiToInteger64(Register dst, Register src) { |
| 1048 ASSERT_EQ(0, kSmiTag); | 1048 STATIC_ASSERT(kSmiTag == 0); |
| 1049 if (!dst.is(src)) { | 1049 if (!dst.is(src)) { |
| 1050 movq(dst, src); | 1050 movq(dst, src); |
| 1051 } | 1051 } |
| 1052 sar(dst, Immediate(kSmiShift)); | 1052 sar(dst, Immediate(kSmiShift)); |
| 1053 } | 1053 } |
| 1054 | 1054 |
| 1055 | 1055 |
| 1056 void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) { | 1056 void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) { |
| 1057 movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte)); | 1057 movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte)); |
| 1058 } | 1058 } |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1174 movq(dst, kScratchRegister); | 1174 movq(dst, kScratchRegister); |
| 1175 } else { | 1175 } else { |
| 1176 movq(dst, src1); | 1176 movq(dst, src1); |
| 1177 or_(dst, src2); | 1177 or_(dst, src2); |
| 1178 JumpIfNotSmi(dst, on_not_smis, near_jump); | 1178 JumpIfNotSmi(dst, on_not_smis, near_jump); |
| 1179 } | 1179 } |
| 1180 } | 1180 } |
| 1181 | 1181 |
| 1182 | 1182 |
| 1183 Condition MacroAssembler::CheckSmi(Register src) { | 1183 Condition MacroAssembler::CheckSmi(Register src) { |
| 1184 ASSERT_EQ(0, kSmiTag); | 1184 STATIC_ASSERT(kSmiTag == 0); |
| 1185 testb(src, Immediate(kSmiTagMask)); | 1185 testb(src, Immediate(kSmiTagMask)); |
| 1186 return zero; | 1186 return zero; |
| 1187 } | 1187 } |
| 1188 | 1188 |
| 1189 | 1189 |
| 1190 Condition MacroAssembler::CheckSmi(const Operand& src) { | 1190 Condition MacroAssembler::CheckSmi(const Operand& src) { |
| 1191 ASSERT_EQ(0, kSmiTag); | 1191 STATIC_ASSERT(kSmiTag == 0); |
| 1192 testb(src, Immediate(kSmiTagMask)); | 1192 testb(src, Immediate(kSmiTagMask)); |
| 1193 return zero; | 1193 return zero; |
| 1194 } | 1194 } |
| 1195 | 1195 |
| 1196 | 1196 |
| 1197 Condition MacroAssembler::CheckNonNegativeSmi(Register src) { | 1197 Condition MacroAssembler::CheckNonNegativeSmi(Register src) { |
| 1198 ASSERT_EQ(0, kSmiTag); | 1198 STATIC_ASSERT(kSmiTag == 0); |
| 1199 // Test that both bits of the mask 0x8000000000000001 are zero. | 1199 // Test that both bits of the mask 0x8000000000000001 are zero. |
| 1200 movq(kScratchRegister, src); | 1200 movq(kScratchRegister, src); |
| 1201 rol(kScratchRegister, Immediate(1)); | 1201 rol(kScratchRegister, Immediate(1)); |
| 1202 testb(kScratchRegister, Immediate(3)); | 1202 testb(kScratchRegister, Immediate(3)); |
| 1203 return zero; | 1203 return zero; |
| 1204 } | 1204 } |
| 1205 | 1205 |
| 1206 | 1206 |
| 1207 Condition MacroAssembler::CheckBothSmi(Register first, Register second) { | 1207 Condition MacroAssembler::CheckBothSmi(Register first, Register second) { |
| 1208 if (first.is(second)) { | 1208 if (first.is(second)) { |
| 1209 return CheckSmi(first); | 1209 return CheckSmi(first); |
| 1210 } | 1210 } |
| 1211 ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3); | 1211 STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3); |
| 1212 leal(kScratchRegister, Operand(first, second, times_1, 0)); | 1212 leal(kScratchRegister, Operand(first, second, times_1, 0)); |
| 1213 testb(kScratchRegister, Immediate(0x03)); | 1213 testb(kScratchRegister, Immediate(0x03)); |
| 1214 return zero; | 1214 return zero; |
| 1215 } | 1215 } |
| 1216 | 1216 |
| 1217 | 1217 |
| 1218 Condition MacroAssembler::CheckBothNonNegativeSmi(Register first, | 1218 Condition MacroAssembler::CheckBothNonNegativeSmi(Register first, |
| 1219 Register second) { | 1219 Register second) { |
| 1220 if (first.is(second)) { | 1220 if (first.is(second)) { |
| 1221 return CheckNonNegativeSmi(first); | 1221 return CheckNonNegativeSmi(first); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1357 } | 1357 } |
| 1358 | 1358 |
| 1359 | 1359 |
| 1360 void MacroAssembler::SmiTryAddConstant(Register dst, | 1360 void MacroAssembler::SmiTryAddConstant(Register dst, |
| 1361 Register src, | 1361 Register src, |
| 1362 Smi* constant, | 1362 Smi* constant, |
| 1363 Label* on_not_smi_result, | 1363 Label* on_not_smi_result, |
| 1364 Label::Distance near_jump) { | 1364 Label::Distance near_jump) { |
| 1365 // Does not assume that src is a smi. | 1365 // Does not assume that src is a smi. |
| 1366 ASSERT_EQ(static_cast<int>(1), static_cast<int>(kSmiTagMask)); | 1366 ASSERT_EQ(static_cast<int>(1), static_cast<int>(kSmiTagMask)); |
| 1367 ASSERT_EQ(0, kSmiTag); | 1367 STATIC_ASSERT(kSmiTag == 0); |
| 1368 ASSERT(!dst.is(kScratchRegister)); | 1368 ASSERT(!dst.is(kScratchRegister)); |
| 1369 ASSERT(!src.is(kScratchRegister)); | 1369 ASSERT(!src.is(kScratchRegister)); |
| 1370 | 1370 |
| 1371 JumpIfNotSmi(src, on_not_smi_result, near_jump); | 1371 JumpIfNotSmi(src, on_not_smi_result, near_jump); |
| 1372 Register tmp = (dst.is(src) ? kScratchRegister : dst); | 1372 Register tmp = (dst.is(src) ? kScratchRegister : dst); |
| 1373 LoadSmiConstant(tmp, constant); | 1373 LoadSmiConstant(tmp, constant); |
| 1374 addq(tmp, src); | 1374 addq(tmp, src); |
| 1375 j(overflow, on_not_smi_result, near_jump); | 1375 j(overflow, on_not_smi_result, near_jump); |
| 1376 if (dst.is(src)) { | 1376 if (dst.is(src)) { |
| 1377 movq(dst, tmp); | 1377 movq(dst, tmp); |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2061 ASSERT(!src2.is(kScratchRegister)); | 2061 ASSERT(!src2.is(kScratchRegister)); |
| 2062 ASSERT(!dst.is(src1)); | 2062 ASSERT(!dst.is(src1)); |
| 2063 ASSERT(!dst.is(src2)); | 2063 ASSERT(!dst.is(src2)); |
| 2064 // Both operands must not be smis. | 2064 // Both operands must not be smis. |
| 2065 #ifdef DEBUG | 2065 #ifdef DEBUG |
| 2066 if (allow_stub_calls()) { // Check contains a stub call. | 2066 if (allow_stub_calls()) { // Check contains a stub call. |
| 2067 Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2)); | 2067 Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2)); |
| 2068 Check(not_both_smis, "Both registers were smis in SelectNonSmi."); | 2068 Check(not_both_smis, "Both registers were smis in SelectNonSmi."); |
| 2069 } | 2069 } |
| 2070 #endif | 2070 #endif |
| 2071 ASSERT_EQ(0, kSmiTag); | 2071 STATIC_ASSERT(kSmiTag == 0); |
| 2072 ASSERT_EQ(0, Smi::FromInt(0)); | 2072 ASSERT_EQ(0, Smi::FromInt(0)); |
| 2073 movl(kScratchRegister, Immediate(kSmiTagMask)); | 2073 movl(kScratchRegister, Immediate(kSmiTagMask)); |
| 2074 and_(kScratchRegister, src1); | 2074 and_(kScratchRegister, src1); |
| 2075 testl(kScratchRegister, src2); | 2075 testl(kScratchRegister, src2); |
| 2076 // If non-zero then both are smis. | 2076 // If non-zero then both are smis. |
| 2077 j(not_zero, on_not_smis, near_jump); | 2077 j(not_zero, on_not_smis, near_jump); |
| 2078 | 2078 |
| 2079 // Exactly one operand is a smi. | 2079 // Exactly one operand is a smi. |
| 2080 ASSERT_EQ(1, static_cast<int>(kSmiTagMask)); | 2080 ASSERT_EQ(1, static_cast<int>(kSmiTagMask)); |
| 2081 // kScratchRegister still holds src1 & kSmiTag, which is either zero or one. | 2081 // kScratchRegister still holds src1 & kSmiTag, which is either zero or one. |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2762 Check(equal, message); | 2762 Check(equal, message); |
| 2763 } | 2763 } |
| 2764 | 2764 |
| 2765 | 2765 |
| 2766 | 2766 |
| 2767 Condition MacroAssembler::IsObjectStringType(Register heap_object, | 2767 Condition MacroAssembler::IsObjectStringType(Register heap_object, |
| 2768 Register map, | 2768 Register map, |
| 2769 Register instance_type) { | 2769 Register instance_type) { |
| 2770 movq(map, FieldOperand(heap_object, HeapObject::kMapOffset)); | 2770 movq(map, FieldOperand(heap_object, HeapObject::kMapOffset)); |
| 2771 movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); | 2771 movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); |
| 2772 ASSERT(kNotStringTag != 0); | 2772 STATIC_ASSERT(kNotStringTag != 0); |
| 2773 testb(instance_type, Immediate(kIsNotStringMask)); | 2773 testb(instance_type, Immediate(kIsNotStringMask)); |
| 2774 return zero; | 2774 return zero; |
| 2775 } | 2775 } |
| 2776 | 2776 |
| 2777 | 2777 |
| 2778 void MacroAssembler::TryGetFunctionPrototype(Register function, | 2778 void MacroAssembler::TryGetFunctionPrototype(Register function, |
| 2779 Register result, | 2779 Register result, |
| 2780 Label* miss) { | 2780 Label* miss) { |
| 2781 // Check that the receiver isn't a smi. | 2781 // Check that the receiver isn't a smi. |
| 2782 testl(function, Immediate(kSmiTagMask)); | 2782 testl(function, Immediate(kSmiTagMask)); |
| (...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3686 // Set the map, length and hash field. | 3686 // Set the map, length and hash field. |
| 3687 LoadRoot(kScratchRegister, Heap::kAsciiStringMapRootIndex); | 3687 LoadRoot(kScratchRegister, Heap::kAsciiStringMapRootIndex); |
| 3688 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 3688 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
| 3689 Integer32ToSmi(scratch1, length); | 3689 Integer32ToSmi(scratch1, length); |
| 3690 movq(FieldOperand(result, String::kLengthOffset), scratch1); | 3690 movq(FieldOperand(result, String::kLengthOffset), scratch1); |
| 3691 movq(FieldOperand(result, String::kHashFieldOffset), | 3691 movq(FieldOperand(result, String::kHashFieldOffset), |
| 3692 Immediate(String::kEmptyHashField)); | 3692 Immediate(String::kEmptyHashField)); |
| 3693 } | 3693 } |
| 3694 | 3694 |
| 3695 | 3695 |
| 3696 void MacroAssembler::AllocateConsString(Register result, | 3696 void MacroAssembler::AllocateTwoByteConsString(Register result, |
| 3697 Register scratch1, | 3697 Register scratch1, |
| 3698 Register scratch2, | 3698 Register scratch2, |
| 3699 Label* gc_required) { | 3699 Label* gc_required) { |
| 3700 // Allocate heap number in new space. | 3700 // Allocate heap number in new space. |
| 3701 AllocateInNewSpace(ConsString::kSize, | 3701 AllocateInNewSpace(ConsString::kSize, |
| 3702 result, | 3702 result, |
| 3703 scratch1, | 3703 scratch1, |
| 3704 scratch2, | 3704 scratch2, |
| 3705 gc_required, | 3705 gc_required, |
| 3706 TAG_OBJECT); | 3706 TAG_OBJECT); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3722 scratch2, | 3722 scratch2, |
| 3723 gc_required, | 3723 gc_required, |
| 3724 TAG_OBJECT); | 3724 TAG_OBJECT); |
| 3725 | 3725 |
| 3726 // Set the map. The other fields are left uninitialized. | 3726 // Set the map. The other fields are left uninitialized. |
| 3727 LoadRoot(kScratchRegister, Heap::kConsAsciiStringMapRootIndex); | 3727 LoadRoot(kScratchRegister, Heap::kConsAsciiStringMapRootIndex); |
| 3728 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 3728 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
| 3729 } | 3729 } |
| 3730 | 3730 |
| 3731 | 3731 |
| 3732 void MacroAssembler::AllocateTwoByteSlicedString(Register result, |
| 3733 Register scratch1, |
| 3734 Register scratch2, |
| 3735 Label* gc_required) { |
| 3736 // Allocate heap number in new space. |
| 3737 AllocateInNewSpace(SlicedString::kSize, |
| 3738 result, |
| 3739 scratch1, |
| 3740 scratch2, |
| 3741 gc_required, |
| 3742 TAG_OBJECT); |
| 3743 |
| 3744 // Set the map. The other fields are left uninitialized. |
| 3745 LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex); |
| 3746 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
| 3747 } |
| 3748 |
| 3749 |
| 3750 void MacroAssembler::AllocateAsciiSlicedString(Register result, |
| 3751 Register scratch1, |
| 3752 Register scratch2, |
| 3753 Label* gc_required) { |
| 3754 // Allocate heap number in new space. |
| 3755 AllocateInNewSpace(SlicedString::kSize, |
| 3756 result, |
| 3757 scratch1, |
| 3758 scratch2, |
| 3759 gc_required, |
| 3760 TAG_OBJECT); |
| 3761 |
| 3762 // Set the map. The other fields are left uninitialized. |
| 3763 LoadRoot(kScratchRegister, Heap::kSlicedAsciiStringMapRootIndex); |
| 3764 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
| 3765 } |
| 3766 |
| 3767 |
| 3732 // Copy memory, byte-by-byte, from source to destination. Not optimized for | 3768 // Copy memory, byte-by-byte, from source to destination. Not optimized for |
| 3733 // long or aligned copies. The contents of scratch and length are destroyed. | 3769 // long or aligned copies. The contents of scratch and length are destroyed. |
| 3734 // Destination is incremented by length, source, length and scratch are | 3770 // Destination is incremented by length, source, length and scratch are |
| 3735 // clobbered. | 3771 // clobbered. |
| 3736 // A simpler loop is faster on small copies, but slower on large ones. | 3772 // A simpler loop is faster on small copies, but slower on large ones. |
| 3737 // The cld() instruction must have been emitted, to set the direction flag(), | 3773 // The cld() instruction must have been emitted, to set the direction flag(), |
| 3738 // before calling this function. | 3774 // before calling this function. |
| 3739 void MacroAssembler::CopyBytes(Register destination, | 3775 void MacroAssembler::CopyBytes(Register destination, |
| 3740 Register source, | 3776 Register source, |
| 3741 Register length, | 3777 Register length, |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3989 // marked black immediately so this code is not hit). | 4025 // marked black immediately so this code is not hit). |
| 3990 void MacroAssembler::JumpIfDataObject( | 4026 void MacroAssembler::JumpIfDataObject( |
| 3991 Register value, | 4027 Register value, |
| 3992 Register scratch, | 4028 Register scratch, |
| 3993 Label* not_data_object, | 4029 Label* not_data_object, |
| 3994 Label::Distance not_data_object_distance) { | 4030 Label::Distance not_data_object_distance) { |
| 3995 Label is_data_object; | 4031 Label is_data_object; |
| 3996 movq(scratch, FieldOperand(value, HeapObject::kMapOffset)); | 4032 movq(scratch, FieldOperand(value, HeapObject::kMapOffset)); |
| 3997 CompareRoot(scratch, Heap::kHeapNumberMapRootIndex); | 4033 CompareRoot(scratch, Heap::kHeapNumberMapRootIndex); |
| 3998 j(equal, &is_data_object, Label::kNear); | 4034 j(equal, &is_data_object, Label::kNear); |
| 3999 ASSERT(kConsStringTag == 1 && kIsConsStringMask == 1); | 4035 ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); |
| 4000 ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); | 4036 ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); |
| 4001 // If it's a string and it's not a cons string then it's an object containing | 4037 // If it's a string and it's not a cons string then it's an object containing |
| 4002 // no GC pointers. | 4038 // no GC pointers. |
| 4003 testb(FieldOperand(scratch, Map::kInstanceTypeOffset), | 4039 testb(FieldOperand(scratch, Map::kInstanceTypeOffset), |
| 4004 Immediate(kIsConsStringMask | kIsNotStringMask)); | 4040 Immediate(kIsIndirectStringMask | kIsNotStringMask)); |
| 4005 j(not_zero, not_data_object, not_data_object_distance); | 4041 j(not_zero, not_data_object, not_data_object_distance); |
| 4006 bind(&is_data_object); | 4042 bind(&is_data_object); |
| 4007 } | 4043 } |
| 4008 | 4044 |
| 4009 | 4045 |
| 4010 void MacroAssembler::GetMarkBits(Register addr_reg, | 4046 void MacroAssembler::GetMarkBits(Register addr_reg, |
| 4011 Register bitmap_reg, | 4047 Register bitmap_reg, |
| 4012 Register mask_reg) { | 4048 Register mask_reg) { |
| 4013 ASSERT(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx)); | 4049 ASSERT(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx)); |
| 4014 movq(bitmap_reg, addr_reg); | 4050 movq(bitmap_reg, addr_reg); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4075 | 4111 |
| 4076 // Check for heap-number | 4112 // Check for heap-number |
| 4077 movq(map, FieldOperand(value, HeapObject::kMapOffset)); | 4113 movq(map, FieldOperand(value, HeapObject::kMapOffset)); |
| 4078 CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 4114 CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
| 4079 j(not_equal, ¬_heap_number, Label::kNear); | 4115 j(not_equal, ¬_heap_number, Label::kNear); |
| 4080 movq(length, Immediate(HeapNumber::kSize)); | 4116 movq(length, Immediate(HeapNumber::kSize)); |
| 4081 jmp(&is_data_object, Label::kNear); | 4117 jmp(&is_data_object, Label::kNear); |
| 4082 | 4118 |
| 4083 bind(¬_heap_number); | 4119 bind(¬_heap_number); |
| 4084 // Check for strings. | 4120 // Check for strings. |
| 4085 ASSERT(kConsStringTag == 1 && kIsConsStringMask == 1); | 4121 ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); |
| 4086 ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); | 4122 ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); |
| 4087 // If it's a string and it's not a cons string then it's an object containing | 4123 // If it's a string and it's not a cons string then it's an object containing |
| 4088 // no GC pointers. | 4124 // no GC pointers. |
| 4089 Register instance_type = rcx; | 4125 Register instance_type = rcx; |
| 4090 movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); | 4126 movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); |
| 4091 testb(instance_type, Immediate(kIsConsStringMask | kIsNotStringMask)); | 4127 testb(instance_type, Immediate(kIsIndirectStringMask | kIsNotStringMask)); |
| 4092 j(not_zero, value_is_white_and_not_data); | 4128 j(not_zero, value_is_white_and_not_data); |
| 4093 // It's a non-cons string. | 4129 // It's a non-indirect (non-cons and non-slice) string. |
| 4094 // If it's external, the length is just ExternalString::kSize. | 4130 // If it's external, the length is just ExternalString::kSize. |
| 4095 // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). | 4131 // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). |
| 4096 Label not_external; | 4132 Label not_external; |
| 4097 // External strings are the only ones with the kExternalStringTag bit | 4133 // External strings are the only ones with the kExternalStringTag bit |
| 4098 // set. | 4134 // set. |
| 4099 ASSERT_EQ(0, kSeqStringTag & kExternalStringTag); | 4135 ASSERT_EQ(0, kSeqStringTag & kExternalStringTag); |
| 4100 ASSERT_EQ(0, kConsStringTag & kExternalStringTag); | 4136 ASSERT_EQ(0, kConsStringTag & kExternalStringTag); |
| 4101 testb(instance_type, Immediate(kExternalStringTag)); | 4137 testb(instance_type, Immediate(kExternalStringTag)); |
| 4102 j(zero, ¬_external, Label::kNear); | 4138 j(zero, ¬_external, Label::kNear); |
| 4103 movq(length, Immediate(ExternalString::kSize)); | 4139 movq(length, Immediate(ExternalString::kSize)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4122 | 4158 |
| 4123 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); | 4159 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); |
| 4124 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); | 4160 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); |
| 4125 | 4161 |
| 4126 bind(&done); | 4162 bind(&done); |
| 4127 } | 4163 } |
| 4128 | 4164 |
| 4129 } } // namespace v8::internal | 4165 } } // namespace v8::internal |
| 4130 | 4166 |
| 4131 #endif // V8_TARGET_ARCH_X64 | 4167 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |