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_X64 | 5 #if V8_TARGET_ARCH_X64 |
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 2529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2540 andl(scratch1, Immediate(kFlatOneByteStringMask)); | 2540 andl(scratch1, Immediate(kFlatOneByteStringMask)); |
2541 andl(scratch2, Immediate(kFlatOneByteStringMask)); | 2541 andl(scratch2, Immediate(kFlatOneByteStringMask)); |
2542 // Interleave the bits to check both scratch1 and scratch2 in one test. | 2542 // Interleave the bits to check both scratch1 and scratch2 in one test. |
2543 DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3)); | 2543 DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3)); |
2544 leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); | 2544 leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); |
2545 cmpl(scratch1, | 2545 cmpl(scratch1, |
2546 Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3))); | 2546 Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3))); |
2547 j(not_equal, on_fail, near_jump); | 2547 j(not_equal, on_fail, near_jump); |
2548 } | 2548 } |
2549 | 2549 |
2550 | |
2551 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte( | |
2552 Register instance_type, Register scratch, Label* failure, | |
2553 Label::Distance near_jump) { | |
2554 if (!scratch.is(instance_type)) { | |
2555 movl(scratch, instance_type); | |
2556 } | |
2557 | |
2558 const int kFlatOneByteStringMask = | |
2559 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; | |
2560 | |
2561 andl(scratch, Immediate(kFlatOneByteStringMask)); | |
2562 cmpl(scratch, Immediate(kStringTag | kSeqStringTag | kOneByteStringTag)); | |
2563 j(not_equal, failure, near_jump); | |
2564 } | |
2565 | |
2566 | |
2567 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( | 2550 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( |
2568 Register first_object_instance_type, Register second_object_instance_type, | 2551 Register first_object_instance_type, Register second_object_instance_type, |
2569 Register scratch1, Register scratch2, Label* on_fail, | 2552 Register scratch1, Register scratch2, Label* on_fail, |
2570 Label::Distance near_jump) { | 2553 Label::Distance near_jump) { |
2571 // Load instance type for both strings. | 2554 // Load instance type for both strings. |
2572 movp(scratch1, first_object_instance_type); | 2555 movp(scratch1, first_object_instance_type); |
2573 movp(scratch2, second_object_instance_type); | 2556 movp(scratch2, second_object_instance_type); |
2574 | 2557 |
2575 // Check that both are flat one-byte strings. | 2558 // Check that both are flat one-byte strings. |
2576 DCHECK(kNotStringTag != 0); | 2559 DCHECK(kNotStringTag != 0); |
(...skipping 2314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4891 | 4874 |
4892 Heap::RootListIndex map_index = mode == MUTABLE | 4875 Heap::RootListIndex map_index = mode == MUTABLE |
4893 ? Heap::kMutableHeapNumberMapRootIndex | 4876 ? Heap::kMutableHeapNumberMapRootIndex |
4894 : Heap::kHeapNumberMapRootIndex; | 4877 : Heap::kHeapNumberMapRootIndex; |
4895 | 4878 |
4896 // Set the map. | 4879 // Set the map. |
4897 LoadRoot(kScratchRegister, map_index); | 4880 LoadRoot(kScratchRegister, map_index); |
4898 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 4881 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
4899 } | 4882 } |
4900 | 4883 |
4901 | |
4902 void MacroAssembler::AllocateTwoByteString(Register result, | |
4903 Register length, | |
4904 Register scratch1, | |
4905 Register scratch2, | |
4906 Register scratch3, | |
4907 Label* gc_required) { | |
4908 // Calculate the number of bytes needed for the characters in the string while | |
4909 // observing object alignment. | |
4910 const int kHeaderAlignment = SeqTwoByteString::kHeaderSize & | |
4911 kObjectAlignmentMask; | |
4912 DCHECK(kShortSize == 2); | |
4913 // scratch1 = length * 2 + kObjectAlignmentMask. | |
4914 leap(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + | |
4915 kHeaderAlignment)); | |
4916 andp(scratch1, Immediate(~kObjectAlignmentMask)); | |
4917 if (kHeaderAlignment > 0) { | |
4918 subp(scratch1, Immediate(kHeaderAlignment)); | |
4919 } | |
4920 | |
4921 // Allocate two byte string in new space. | |
4922 Allocate(SeqTwoByteString::kHeaderSize, times_1, scratch1, result, scratch2, | |
4923 scratch3, gc_required, NO_ALLOCATION_FLAGS); | |
4924 | |
4925 // Set the map, length and hash field. | |
4926 LoadRoot(kScratchRegister, Heap::kStringMapRootIndex); | |
4927 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | |
4928 Integer32ToSmi(scratch1, length); | |
4929 movp(FieldOperand(result, String::kLengthOffset), scratch1); | |
4930 movp(FieldOperand(result, String::kHashFieldOffset), | |
4931 Immediate(String::kEmptyHashField)); | |
4932 } | |
4933 | |
4934 | |
4935 void MacroAssembler::AllocateOneByteString(Register result, Register length, | |
4936 Register scratch1, Register scratch2, | |
4937 Register scratch3, | |
4938 Label* gc_required) { | |
4939 // Calculate the number of bytes needed for the characters in the string while | |
4940 // observing object alignment. | |
4941 const int kHeaderAlignment = SeqOneByteString::kHeaderSize & | |
4942 kObjectAlignmentMask; | |
4943 movl(scratch1, length); | |
4944 DCHECK(kCharSize == 1); | |
4945 addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); | |
4946 andp(scratch1, Immediate(~kObjectAlignmentMask)); | |
4947 if (kHeaderAlignment > 0) { | |
4948 subp(scratch1, Immediate(kHeaderAlignment)); | |
4949 } | |
4950 | |
4951 // Allocate one-byte string in new space. | |
4952 Allocate(SeqOneByteString::kHeaderSize, times_1, scratch1, result, scratch2, | |
4953 scratch3, gc_required, NO_ALLOCATION_FLAGS); | |
4954 | |
4955 // Set the map, length and hash field. | |
4956 LoadRoot(kScratchRegister, Heap::kOneByteStringMapRootIndex); | |
4957 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | |
4958 Integer32ToSmi(scratch1, length); | |
4959 movp(FieldOperand(result, String::kLengthOffset), scratch1); | |
4960 movp(FieldOperand(result, String::kHashFieldOffset), | |
4961 Immediate(String::kEmptyHashField)); | |
4962 } | |
4963 | |
4964 | |
4965 void MacroAssembler::AllocateTwoByteConsString(Register result, | |
4966 Register scratch1, | |
4967 Register scratch2, | |
4968 Label* gc_required) { | |
4969 // Allocate heap number in new space. | |
4970 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | |
4971 NO_ALLOCATION_FLAGS); | |
4972 | |
4973 // Set the map. The other fields are left uninitialized. | |
4974 LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex); | |
4975 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | |
4976 } | |
4977 | |
4978 | |
4979 void MacroAssembler::AllocateOneByteConsString(Register result, | |
4980 Register scratch1, | |
4981 Register scratch2, | |
4982 Label* gc_required) { | |
4983 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | |
4984 NO_ALLOCATION_FLAGS); | |
4985 | |
4986 // Set the map. The other fields are left uninitialized. | |
4987 LoadRoot(kScratchRegister, Heap::kConsOneByteStringMapRootIndex); | |
4988 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | |
4989 } | |
4990 | |
4991 | |
4992 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | |
4993 Register scratch1, | |
4994 Register scratch2, | |
4995 Label* gc_required) { | |
4996 // Allocate heap number in new space. | |
4997 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | |
4998 NO_ALLOCATION_FLAGS); | |
4999 | |
5000 // Set the map. The other fields are left uninitialized. | |
5001 LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex); | |
5002 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | |
5003 } | |
5004 | |
5005 | |
5006 void MacroAssembler::AllocateOneByteSlicedString(Register result, | |
5007 Register scratch1, | |
5008 Register scratch2, | |
5009 Label* gc_required) { | |
5010 // Allocate heap number in new space. | |
5011 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | |
5012 NO_ALLOCATION_FLAGS); | |
5013 | |
5014 // Set the map. The other fields are left uninitialized. | |
5015 LoadRoot(kScratchRegister, Heap::kSlicedOneByteStringMapRootIndex); | |
5016 movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | |
5017 } | |
5018 | |
5019 | |
5020 void MacroAssembler::AllocateJSValue(Register result, Register constructor, | 4884 void MacroAssembler::AllocateJSValue(Register result, Register constructor, |
5021 Register value, Register scratch, | 4885 Register value, Register scratch, |
5022 Label* gc_required) { | 4886 Label* gc_required) { |
5023 DCHECK(!result.is(constructor)); | 4887 DCHECK(!result.is(constructor)); |
5024 DCHECK(!result.is(scratch)); | 4888 DCHECK(!result.is(scratch)); |
5025 DCHECK(!result.is(value)); | 4889 DCHECK(!result.is(value)); |
5026 | 4890 |
5027 // Allocate JSValue in new space. | 4891 // Allocate JSValue in new space. |
5028 Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, | 4892 Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, |
5029 NO_ALLOCATION_FLAGS); | 4893 NO_ALLOCATION_FLAGS); |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5433 movl(rax, dividend); | 5297 movl(rax, dividend); |
5434 shrl(rax, Immediate(31)); | 5298 shrl(rax, Immediate(31)); |
5435 addl(rdx, rax); | 5299 addl(rdx, rax); |
5436 } | 5300 } |
5437 | 5301 |
5438 | 5302 |
5439 } // namespace internal | 5303 } // namespace internal |
5440 } // namespace v8 | 5304 } // namespace v8 |
5441 | 5305 |
5442 #endif // V8_TARGET_ARCH_X64 | 5306 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |