| 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 |