OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 JumpIfSmi(value, &done, Label::kNear); | 447 JumpIfSmi(value, &done, Label::kNear); |
448 } | 448 } |
449 | 449 |
450 // Although the object register is tagged, the offset is relative to the start | 450 // Although the object register is tagged, the offset is relative to the start |
451 // of the object, so so offset must be a multiple of kPointerSize. | 451 // of the object, so so offset must be a multiple of kPointerSize. |
452 DCHECK(IsAligned(offset, kPointerSize)); | 452 DCHECK(IsAligned(offset, kPointerSize)); |
453 | 453 |
454 lea(dst, FieldOperand(object, offset)); | 454 lea(dst, FieldOperand(object, offset)); |
455 if (emit_debug_code()) { | 455 if (emit_debug_code()) { |
456 Label ok; | 456 Label ok; |
457 test_b(dst, (1 << kPointerSizeLog2) - 1); | 457 test_b(dst, Immediate((1 << kPointerSizeLog2) - 1)); |
458 j(zero, &ok, Label::kNear); | 458 j(zero, &ok, Label::kNear); |
459 int3(); | 459 int3(); |
460 bind(&ok); | 460 bind(&ok); |
461 } | 461 } |
462 | 462 |
463 RecordWrite(object, dst, value, save_fp, remembered_set_action, | 463 RecordWrite(object, dst, value, save_fp, remembered_set_action, |
464 OMIT_SMI_CHECK, pointers_to_here_check_for_value); | 464 OMIT_SMI_CHECK, pointers_to_here_check_for_value); |
465 | 465 |
466 bind(&done); | 466 bind(&done); |
467 | 467 |
(...skipping 12 matching lines...) Expand all Loading... |
480 Register scratch1, | 480 Register scratch1, |
481 Register scratch2, | 481 Register scratch2, |
482 SaveFPRegsMode save_fp) { | 482 SaveFPRegsMode save_fp) { |
483 Label done; | 483 Label done; |
484 | 484 |
485 Register address = scratch1; | 485 Register address = scratch1; |
486 Register value = scratch2; | 486 Register value = scratch2; |
487 if (emit_debug_code()) { | 487 if (emit_debug_code()) { |
488 Label ok; | 488 Label ok; |
489 lea(address, FieldOperand(object, HeapObject::kMapOffset)); | 489 lea(address, FieldOperand(object, HeapObject::kMapOffset)); |
490 test_b(address, (1 << kPointerSizeLog2) - 1); | 490 test_b(address, Immediate((1 << kPointerSizeLog2) - 1)); |
491 j(zero, &ok, Label::kNear); | 491 j(zero, &ok, Label::kNear); |
492 int3(); | 492 int3(); |
493 bind(&ok); | 493 bind(&ok); |
494 } | 494 } |
495 | 495 |
496 DCHECK(!object.is(value)); | 496 DCHECK(!object.is(value)); |
497 DCHECK(!object.is(address)); | 497 DCHECK(!object.is(address)); |
498 DCHECK(!value.is(address)); | 498 DCHECK(!value.is(address)); |
499 AssertNotSmi(object); | 499 AssertNotSmi(object); |
500 | 500 |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 | 801 |
802 void MacroAssembler::CmpObjectType(Register heap_object, | 802 void MacroAssembler::CmpObjectType(Register heap_object, |
803 InstanceType type, | 803 InstanceType type, |
804 Register map) { | 804 Register map) { |
805 mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); | 805 mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); |
806 CmpInstanceType(map, type); | 806 CmpInstanceType(map, type); |
807 } | 807 } |
808 | 808 |
809 | 809 |
810 void MacroAssembler::CmpInstanceType(Register map, InstanceType type) { | 810 void MacroAssembler::CmpInstanceType(Register map, InstanceType type) { |
811 cmpb(FieldOperand(map, Map::kInstanceTypeOffset), | 811 cmpb(FieldOperand(map, Map::kInstanceTypeOffset), Immediate(type)); |
812 static_cast<int8_t>(type)); | |
813 } | 812 } |
814 | 813 |
815 | 814 |
816 void MacroAssembler::CheckFastElements(Register map, | 815 void MacroAssembler::CheckFastElements(Register map, |
817 Label* fail, | 816 Label* fail, |
818 Label::Distance distance) { | 817 Label::Distance distance) { |
819 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 818 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
820 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 819 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
821 STATIC_ASSERT(FAST_ELEMENTS == 2); | 820 STATIC_ASSERT(FAST_ELEMENTS == 2); |
822 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | 821 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
823 cmpb(FieldOperand(map, Map::kBitField2Offset), | 822 cmpb(FieldOperand(map, Map::kBitField2Offset), |
824 Map::kMaximumBitField2FastHoleyElementValue); | 823 Immediate(Map::kMaximumBitField2FastHoleyElementValue)); |
825 j(above, fail, distance); | 824 j(above, fail, distance); |
826 } | 825 } |
827 | 826 |
828 | 827 |
829 void MacroAssembler::CheckFastObjectElements(Register map, | 828 void MacroAssembler::CheckFastObjectElements(Register map, |
830 Label* fail, | 829 Label* fail, |
831 Label::Distance distance) { | 830 Label::Distance distance) { |
832 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 831 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
833 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 832 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
834 STATIC_ASSERT(FAST_ELEMENTS == 2); | 833 STATIC_ASSERT(FAST_ELEMENTS == 2); |
835 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | 834 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
836 cmpb(FieldOperand(map, Map::kBitField2Offset), | 835 cmpb(FieldOperand(map, Map::kBitField2Offset), |
837 Map::kMaximumBitField2FastHoleySmiElementValue); | 836 Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); |
838 j(below_equal, fail, distance); | 837 j(below_equal, fail, distance); |
839 cmpb(FieldOperand(map, Map::kBitField2Offset), | 838 cmpb(FieldOperand(map, Map::kBitField2Offset), |
840 Map::kMaximumBitField2FastHoleyElementValue); | 839 Immediate(Map::kMaximumBitField2FastHoleyElementValue)); |
841 j(above, fail, distance); | 840 j(above, fail, distance); |
842 } | 841 } |
843 | 842 |
844 | 843 |
845 void MacroAssembler::CheckFastSmiElements(Register map, | 844 void MacroAssembler::CheckFastSmiElements(Register map, |
846 Label* fail, | 845 Label* fail, |
847 Label::Distance distance) { | 846 Label::Distance distance) { |
848 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 847 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
849 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 848 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
850 cmpb(FieldOperand(map, Map::kBitField2Offset), | 849 cmpb(FieldOperand(map, Map::kBitField2Offset), |
851 Map::kMaximumBitField2FastHoleySmiElementValue); | 850 Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); |
852 j(above, fail, distance); | 851 j(above, fail, distance); |
853 } | 852 } |
854 | 853 |
855 | 854 |
856 void MacroAssembler::StoreNumberToDoubleElements( | 855 void MacroAssembler::StoreNumberToDoubleElements( |
857 Register maybe_number, | 856 Register maybe_number, |
858 Register elements, | 857 Register elements, |
859 Register key, | 858 Register key, |
860 Register scratch1, | 859 Register scratch1, |
861 XMMRegister scratch2, | 860 XMMRegister scratch2, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 test(instance_type, Immediate(kIsNotStringMask)); | 929 test(instance_type, Immediate(kIsNotStringMask)); |
931 return zero; | 930 return zero; |
932 } | 931 } |
933 | 932 |
934 | 933 |
935 Condition MacroAssembler::IsObjectNameType(Register heap_object, | 934 Condition MacroAssembler::IsObjectNameType(Register heap_object, |
936 Register map, | 935 Register map, |
937 Register instance_type) { | 936 Register instance_type) { |
938 mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); | 937 mov(map, FieldOperand(heap_object, HeapObject::kMapOffset)); |
939 movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); | 938 movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); |
940 cmpb(instance_type, static_cast<uint8_t>(LAST_NAME_TYPE)); | 939 cmpb(instance_type, Immediate(LAST_NAME_TYPE)); |
941 return below_equal; | 940 return below_equal; |
942 } | 941 } |
943 | 942 |
944 | 943 |
945 void MacroAssembler::FCmp() { | 944 void MacroAssembler::FCmp() { |
946 fucomip(); | 945 fucomip(); |
947 fstp(0); | 946 fstp(0); |
948 } | 947 } |
949 | 948 |
950 | 949 |
(...skipping 1045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 | 1995 |
1997 | 1996 |
1998 void MacroAssembler::BooleanBitTest(Register object, | 1997 void MacroAssembler::BooleanBitTest(Register object, |
1999 int field_offset, | 1998 int field_offset, |
2000 int bit_index) { | 1999 int bit_index) { |
2001 bit_index += kSmiTagSize + kSmiShiftSize; | 2000 bit_index += kSmiTagSize + kSmiShiftSize; |
2002 DCHECK(base::bits::IsPowerOfTwo32(kBitsPerByte)); | 2001 DCHECK(base::bits::IsPowerOfTwo32(kBitsPerByte)); |
2003 int byte_index = bit_index / kBitsPerByte; | 2002 int byte_index = bit_index / kBitsPerByte; |
2004 int byte_bit_index = bit_index & (kBitsPerByte - 1); | 2003 int byte_bit_index = bit_index & (kBitsPerByte - 1); |
2005 test_b(FieldOperand(object, field_offset + byte_index), | 2004 test_b(FieldOperand(object, field_offset + byte_index), |
2006 static_cast<byte>(1 << byte_bit_index)); | 2005 Immediate(1 << byte_bit_index)); |
2007 } | 2006 } |
2008 | 2007 |
2009 | 2008 |
2010 | 2009 |
2011 void MacroAssembler::NegativeZeroTest(Register result, | 2010 void MacroAssembler::NegativeZeroTest(Register result, |
2012 Register op, | 2011 Register op, |
2013 Label* then_label) { | 2012 Label* then_label) { |
2014 Label ok; | 2013 Label ok; |
2015 test(result, result); | 2014 test(result, result); |
2016 j(not_zero, &ok, Label::kNear); | 2015 j(not_zero, &ok, Label::kNear); |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2317 } | 2316 } |
2318 } | 2317 } |
2319 | 2318 |
2320 | 2319 |
2321 void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, | 2320 void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, |
2322 const ParameterCount& expected, | 2321 const ParameterCount& expected, |
2323 const ParameterCount& actual) { | 2322 const ParameterCount& actual) { |
2324 Label skip_flooding; | 2323 Label skip_flooding; |
2325 ExternalReference step_in_enabled = | 2324 ExternalReference step_in_enabled = |
2326 ExternalReference::debug_step_in_enabled_address(isolate()); | 2325 ExternalReference::debug_step_in_enabled_address(isolate()); |
2327 cmpb(Operand::StaticVariable(step_in_enabled), 0); | 2326 cmpb(Operand::StaticVariable(step_in_enabled), Immediate(0)); |
2328 j(equal, &skip_flooding); | 2327 j(equal, &skip_flooding); |
2329 { | 2328 { |
2330 FrameScope frame(this, | 2329 FrameScope frame(this, |
2331 has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); | 2330 has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); |
2332 if (expected.is_reg()) { | 2331 if (expected.is_reg()) { |
2333 SmiTag(expected.reg()); | 2332 SmiTag(expected.reg()); |
2334 Push(expected.reg()); | 2333 Push(expected.reg()); |
2335 } | 2334 } |
2336 if (actual.is_reg()) { | 2335 if (actual.is_reg()) { |
2337 SmiTag(actual.reg()); | 2336 SmiTag(actual.reg()); |
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3007 } | 3006 } |
3008 | 3007 |
3009 | 3008 |
3010 void MacroAssembler::JumpIfNotUniqueNameInstanceType(Operand operand, | 3009 void MacroAssembler::JumpIfNotUniqueNameInstanceType(Operand operand, |
3011 Label* not_unique_name, | 3010 Label* not_unique_name, |
3012 Label::Distance distance) { | 3011 Label::Distance distance) { |
3013 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); | 3012 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); |
3014 Label succeed; | 3013 Label succeed; |
3015 test(operand, Immediate(kIsNotStringMask | kIsNotInternalizedMask)); | 3014 test(operand, Immediate(kIsNotStringMask | kIsNotInternalizedMask)); |
3016 j(zero, &succeed); | 3015 j(zero, &succeed); |
3017 cmpb(operand, static_cast<uint8_t>(SYMBOL_TYPE)); | 3016 cmpb(operand, Immediate(SYMBOL_TYPE)); |
3018 j(not_equal, not_unique_name, distance); | 3017 j(not_equal, not_unique_name, distance); |
3019 | 3018 |
3020 bind(&succeed); | 3019 bind(&succeed); |
3021 } | 3020 } |
3022 | 3021 |
3023 | 3022 |
3024 void MacroAssembler::EmitSeqStringSetCharCheck(Register string, | 3023 void MacroAssembler::EmitSeqStringSetCharCheck(Register string, |
3025 Register index, | 3024 Register index, |
3026 Register value, | 3025 Register value, |
3027 uint32_t encoding_mask) { | 3026 uint32_t encoding_mask) { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3155 Label* condition_met, | 3154 Label* condition_met, |
3156 Label::Distance condition_met_distance) { | 3155 Label::Distance condition_met_distance) { |
3157 DCHECK(cc == zero || cc == not_zero); | 3156 DCHECK(cc == zero || cc == not_zero); |
3158 if (scratch.is(object)) { | 3157 if (scratch.is(object)) { |
3159 and_(scratch, Immediate(~Page::kPageAlignmentMask)); | 3158 and_(scratch, Immediate(~Page::kPageAlignmentMask)); |
3160 } else { | 3159 } else { |
3161 mov(scratch, Immediate(~Page::kPageAlignmentMask)); | 3160 mov(scratch, Immediate(~Page::kPageAlignmentMask)); |
3162 and_(scratch, object); | 3161 and_(scratch, object); |
3163 } | 3162 } |
3164 if (mask < (1 << kBitsPerByte)) { | 3163 if (mask < (1 << kBitsPerByte)) { |
3165 test_b(Operand(scratch, MemoryChunk::kFlagsOffset), | 3164 test_b(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); |
3166 static_cast<uint8_t>(mask)); | |
3167 } else { | 3165 } else { |
3168 test(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); | 3166 test(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); |
3169 } | 3167 } |
3170 j(cc, condition_met, condition_met_distance); | 3168 j(cc, condition_met, condition_met_distance); |
3171 } | 3169 } |
3172 | 3170 |
3173 | 3171 |
3174 void MacroAssembler::CheckPageFlagForMap( | 3172 void MacroAssembler::CheckPageFlagForMap( |
3175 Handle<Map> map, | 3173 Handle<Map> map, |
3176 int mask, | 3174 int mask, |
3177 Condition cc, | 3175 Condition cc, |
3178 Label* condition_met, | 3176 Label* condition_met, |
3179 Label::Distance condition_met_distance) { | 3177 Label::Distance condition_met_distance) { |
3180 DCHECK(cc == zero || cc == not_zero); | 3178 DCHECK(cc == zero || cc == not_zero); |
3181 Page* page = Page::FromAddress(map->address()); | 3179 Page* page = Page::FromAddress(map->address()); |
3182 DCHECK(!serializer_enabled()); // Serializer cannot match page_flags. | 3180 DCHECK(!serializer_enabled()); // Serializer cannot match page_flags. |
3183 ExternalReference reference(ExternalReference::page_flags(page)); | 3181 ExternalReference reference(ExternalReference::page_flags(page)); |
3184 // The inlined static address check of the page's flags relies | 3182 // The inlined static address check of the page's flags relies |
3185 // on maps never being compacted. | 3183 // on maps never being compacted. |
3186 DCHECK(!isolate()->heap()->mark_compact_collector()-> | 3184 DCHECK(!isolate()->heap()->mark_compact_collector()-> |
3187 IsOnEvacuationCandidate(*map)); | 3185 IsOnEvacuationCandidate(*map)); |
3188 if (mask < (1 << kBitsPerByte)) { | 3186 if (mask < (1 << kBitsPerByte)) { |
3189 test_b(Operand::StaticVariable(reference), static_cast<uint8_t>(mask)); | 3187 test_b(Operand::StaticVariable(reference), Immediate(mask)); |
3190 } else { | 3188 } else { |
3191 test(Operand::StaticVariable(reference), Immediate(mask)); | 3189 test(Operand::StaticVariable(reference), Immediate(mask)); |
3192 } | 3190 } |
3193 j(cc, condition_met, condition_met_distance); | 3191 j(cc, condition_met, condition_met_distance); |
3194 } | 3192 } |
3195 | 3193 |
3196 | 3194 |
3197 void MacroAssembler::JumpIfBlack(Register object, | 3195 void MacroAssembler::JumpIfBlack(Register object, |
3198 Register scratch0, | 3196 Register scratch0, |
3199 Register scratch1, | 3197 Register scratch1, |
(...skipping 19 matching lines...) Expand all Loading... |
3219 Label other_color, word_boundary; | 3217 Label other_color, word_boundary; |
3220 test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); | 3218 test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); |
3221 j(first_bit == 1 ? zero : not_zero, &other_color, Label::kNear); | 3219 j(first_bit == 1 ? zero : not_zero, &other_color, Label::kNear); |
3222 add(mask_scratch, mask_scratch); // Shift left 1 by adding. | 3220 add(mask_scratch, mask_scratch); // Shift left 1 by adding. |
3223 j(zero, &word_boundary, Label::kNear); | 3221 j(zero, &word_boundary, Label::kNear); |
3224 test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); | 3222 test(mask_scratch, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); |
3225 j(second_bit == 1 ? not_zero : zero, has_color, has_color_distance); | 3223 j(second_bit == 1 ? not_zero : zero, has_color, has_color_distance); |
3226 jmp(&other_color, Label::kNear); | 3224 jmp(&other_color, Label::kNear); |
3227 | 3225 |
3228 bind(&word_boundary); | 3226 bind(&word_boundary); |
3229 test_b(Operand(bitmap_scratch, MemoryChunk::kHeaderSize + kPointerSize), 1); | 3227 test_b(Operand(bitmap_scratch, MemoryChunk::kHeaderSize + kPointerSize), |
| 3228 Immediate(1)); |
3230 | 3229 |
3231 j(second_bit == 1 ? not_zero : zero, has_color, has_color_distance); | 3230 j(second_bit == 1 ? not_zero : zero, has_color, has_color_distance); |
3232 bind(&other_color); | 3231 bind(&other_color); |
3233 } | 3232 } |
3234 | 3233 |
3235 | 3234 |
3236 void MacroAssembler::GetMarkBits(Register addr_reg, | 3235 void MacroAssembler::GetMarkBits(Register addr_reg, |
3237 Register bitmap_reg, | 3236 Register bitmap_reg, |
3238 Register mask_reg) { | 3237 Register mask_reg) { |
3239 DCHECK(!AreAliased(addr_reg, mask_reg, bitmap_reg, ecx)); | 3238 DCHECK(!AreAliased(addr_reg, mask_reg, bitmap_reg, ecx)); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3394 mov(eax, dividend); | 3393 mov(eax, dividend); |
3395 shr(eax, 31); | 3394 shr(eax, 31); |
3396 add(edx, eax); | 3395 add(edx, eax); |
3397 } | 3396 } |
3398 | 3397 |
3399 | 3398 |
3400 } // namespace internal | 3399 } // namespace internal |
3401 } // namespace v8 | 3400 } // namespace v8 |
3402 | 3401 |
3403 #endif // V8_TARGET_ARCH_IA32 | 3402 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |