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 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #if V8_TARGET_ARCH_ARM | 9 #if V8_TARGET_ARCH_ARM |
10 | 10 |
(...skipping 1972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1983 | 1983 |
1984 // Set the map, length and hash field. | 1984 // Set the map, length and hash field. |
1985 InitializeNewString(result, | 1985 InitializeNewString(result, |
1986 length, | 1986 length, |
1987 Heap::kStringMapRootIndex, | 1987 Heap::kStringMapRootIndex, |
1988 scratch1, | 1988 scratch1, |
1989 scratch2); | 1989 scratch2); |
1990 } | 1990 } |
1991 | 1991 |
1992 | 1992 |
1993 void MacroAssembler::AllocateAsciiString(Register result, | 1993 void MacroAssembler::AllocateOneByteString(Register result, Register length, |
1994 Register length, | 1994 Register scratch1, Register scratch2, |
1995 Register scratch1, | 1995 Register scratch3, |
1996 Register scratch2, | 1996 Label* gc_required) { |
1997 Register scratch3, | |
1998 Label* gc_required) { | |
1999 // Calculate the number of bytes needed for the characters in the string while | 1997 // Calculate the number of bytes needed for the characters in the string while |
2000 // observing object alignment. | 1998 // observing object alignment. |
2001 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 1999 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
2002 DCHECK(kCharSize == 1); | 2000 DCHECK(kCharSize == 1); |
2003 add(scratch1, length, | 2001 add(scratch1, length, |
2004 Operand(kObjectAlignmentMask + SeqOneByteString::kHeaderSize)); | 2002 Operand(kObjectAlignmentMask + SeqOneByteString::kHeaderSize)); |
2005 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); | 2003 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
2006 | 2004 |
2007 // Allocate ASCII string in new space. | 2005 // Allocate one-byte string in new space. |
2008 Allocate(scratch1, | 2006 Allocate(scratch1, |
2009 result, | 2007 result, |
2010 scratch2, | 2008 scratch2, |
2011 scratch3, | 2009 scratch3, |
2012 gc_required, | 2010 gc_required, |
2013 TAG_OBJECT); | 2011 TAG_OBJECT); |
2014 | 2012 |
2015 // Set the map, length and hash field. | 2013 // Set the map, length and hash field. |
2016 InitializeNewString(result, | 2014 InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, |
2017 length, | 2015 scratch1, scratch2); |
2018 Heap::kAsciiStringMapRootIndex, | |
2019 scratch1, | |
2020 scratch2); | |
2021 } | 2016 } |
2022 | 2017 |
2023 | 2018 |
2024 void MacroAssembler::AllocateTwoByteConsString(Register result, | 2019 void MacroAssembler::AllocateTwoByteConsString(Register result, |
2025 Register length, | 2020 Register length, |
2026 Register scratch1, | 2021 Register scratch1, |
2027 Register scratch2, | 2022 Register scratch2, |
2028 Label* gc_required) { | 2023 Label* gc_required) { |
2029 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | 2024 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
2030 TAG_OBJECT); | 2025 TAG_OBJECT); |
2031 | 2026 |
2032 InitializeNewString(result, | 2027 InitializeNewString(result, |
2033 length, | 2028 length, |
2034 Heap::kConsStringMapRootIndex, | 2029 Heap::kConsStringMapRootIndex, |
2035 scratch1, | 2030 scratch1, |
2036 scratch2); | 2031 scratch2); |
2037 } | 2032 } |
2038 | 2033 |
2039 | 2034 |
2040 void MacroAssembler::AllocateAsciiConsString(Register result, | 2035 void MacroAssembler::AllocateOneByteConsString(Register result, Register length, |
2041 Register length, | 2036 Register scratch1, |
2042 Register scratch1, | 2037 Register scratch2, |
2043 Register scratch2, | 2038 Label* gc_required) { |
2044 Label* gc_required) { | |
2045 Allocate(ConsString::kSize, | 2039 Allocate(ConsString::kSize, |
2046 result, | 2040 result, |
2047 scratch1, | 2041 scratch1, |
2048 scratch2, | 2042 scratch2, |
2049 gc_required, | 2043 gc_required, |
2050 TAG_OBJECT); | 2044 TAG_OBJECT); |
2051 | 2045 |
2052 InitializeNewString(result, | 2046 InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, |
2053 length, | 2047 scratch1, scratch2); |
2054 Heap::kConsAsciiStringMapRootIndex, | |
2055 scratch1, | |
2056 scratch2); | |
2057 } | 2048 } |
2058 | 2049 |
2059 | 2050 |
2060 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | 2051 void MacroAssembler::AllocateTwoByteSlicedString(Register result, |
2061 Register length, | 2052 Register length, |
2062 Register scratch1, | 2053 Register scratch1, |
2063 Register scratch2, | 2054 Register scratch2, |
2064 Label* gc_required) { | 2055 Label* gc_required) { |
2065 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 2056 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
2066 TAG_OBJECT); | 2057 TAG_OBJECT); |
2067 | 2058 |
2068 InitializeNewString(result, | 2059 InitializeNewString(result, |
2069 length, | 2060 length, |
2070 Heap::kSlicedStringMapRootIndex, | 2061 Heap::kSlicedStringMapRootIndex, |
2071 scratch1, | 2062 scratch1, |
2072 scratch2); | 2063 scratch2); |
2073 } | 2064 } |
2074 | 2065 |
2075 | 2066 |
2076 void MacroAssembler::AllocateAsciiSlicedString(Register result, | 2067 void MacroAssembler::AllocateOneByteSlicedString(Register result, |
2077 Register length, | 2068 Register length, |
2078 Register scratch1, | 2069 Register scratch1, |
2079 Register scratch2, | 2070 Register scratch2, |
2080 Label* gc_required) { | 2071 Label* gc_required) { |
2081 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 2072 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
2082 TAG_OBJECT); | 2073 TAG_OBJECT); |
2083 | 2074 |
2084 InitializeNewString(result, | 2075 InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, |
2085 length, | 2076 scratch1, scratch2); |
2086 Heap::kSlicedAsciiStringMapRootIndex, | |
2087 scratch1, | |
2088 scratch2); | |
2089 } | 2077 } |
2090 | 2078 |
2091 | 2079 |
2092 void MacroAssembler::CompareObjectType(Register object, | 2080 void MacroAssembler::CompareObjectType(Register object, |
2093 Register map, | 2081 Register map, |
2094 Register type_reg, | 2082 Register type_reg, |
2095 InstanceType type) { | 2083 InstanceType type) { |
2096 const Register temp = type_reg.is(no_reg) ? ip : type_reg; | 2084 const Register temp = type_reg.is(no_reg) ? ip : type_reg; |
2097 | 2085 |
2098 ldr(map, FieldMemOperand(object, HeapObject::kMapOffset)); | 2086 ldr(map, FieldMemOperand(object, HeapObject::kMapOffset)); |
(...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3177 // Get the result from the cache. | 3165 // Get the result from the cache. |
3178 bind(&load_result_from_cache); | 3166 bind(&load_result_from_cache); |
3179 ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); | 3167 ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); |
3180 IncrementCounter(isolate()->counters()->number_to_string_native(), | 3168 IncrementCounter(isolate()->counters()->number_to_string_native(), |
3181 1, | 3169 1, |
3182 scratch1, | 3170 scratch1, |
3183 scratch2); | 3171 scratch2); |
3184 } | 3172 } |
3185 | 3173 |
3186 | 3174 |
3187 void MacroAssembler::JumpIfNonSmisNotBothSequentialAsciiStrings( | 3175 void MacroAssembler::JumpIfNonSmisNotBothSequentialOneByteStrings( |
3188 Register first, | 3176 Register first, Register second, Register scratch1, Register scratch2, |
3189 Register second, | |
3190 Register scratch1, | |
3191 Register scratch2, | |
3192 Label* failure) { | 3177 Label* failure) { |
3193 // Test that both first and second are sequential ASCII strings. | 3178 // Test that both first and second are sequential one-byte strings. |
3194 // Assume that they are non-smis. | 3179 // Assume that they are non-smis. |
3195 ldr(scratch1, FieldMemOperand(first, HeapObject::kMapOffset)); | 3180 ldr(scratch1, FieldMemOperand(first, HeapObject::kMapOffset)); |
3196 ldr(scratch2, FieldMemOperand(second, HeapObject::kMapOffset)); | 3181 ldr(scratch2, FieldMemOperand(second, HeapObject::kMapOffset)); |
3197 ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); | 3182 ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); |
3198 ldrb(scratch2, FieldMemOperand(scratch2, Map::kInstanceTypeOffset)); | 3183 ldrb(scratch2, FieldMemOperand(scratch2, Map::kInstanceTypeOffset)); |
3199 | 3184 |
3200 JumpIfBothInstanceTypesAreNotSequentialAscii(scratch1, | 3185 JumpIfBothInstanceTypesAreNotSequentialOneByte(scratch1, scratch2, scratch1, |
3201 scratch2, | 3186 scratch2, failure); |
3202 scratch1, | |
3203 scratch2, | |
3204 failure); | |
3205 } | 3187 } |
3206 | 3188 |
3207 void MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register first, | 3189 void MacroAssembler::JumpIfNotBothSequentialOneByteStrings(Register first, |
3208 Register second, | 3190 Register second, |
3209 Register scratch1, | 3191 Register scratch1, |
3210 Register scratch2, | 3192 Register scratch2, |
3211 Label* failure) { | 3193 Label* failure) { |
3212 // Check that neither is a smi. | 3194 // Check that neither is a smi. |
3213 and_(scratch1, first, Operand(second)); | 3195 and_(scratch1, first, Operand(second)); |
3214 JumpIfSmi(scratch1, failure); | 3196 JumpIfSmi(scratch1, failure); |
3215 JumpIfNonSmisNotBothSequentialAsciiStrings(first, | 3197 JumpIfNonSmisNotBothSequentialOneByteStrings(first, second, scratch1, |
3216 second, | 3198 scratch2, failure); |
3217 scratch1, | |
3218 scratch2, | |
3219 failure); | |
3220 } | 3199 } |
3221 | 3200 |
3222 | 3201 |
3223 void MacroAssembler::JumpIfNotUniqueName(Register reg, | 3202 void MacroAssembler::JumpIfNotUniqueName(Register reg, |
3224 Label* not_unique_name) { | 3203 Label* not_unique_name) { |
3225 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); | 3204 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); |
3226 Label succeed; | 3205 Label succeed; |
3227 tst(reg, Operand(kIsNotStringMask | kIsNotInternalizedMask)); | 3206 tst(reg, Operand(kIsNotStringMask | kIsNotInternalizedMask)); |
3228 b(eq, &succeed); | 3207 b(eq, &succeed); |
3229 cmp(reg, Operand(SYMBOL_TYPE)); | 3208 cmp(reg, Operand(SYMBOL_TYPE)); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3379 | 3358 |
3380 | 3359 |
3381 void MacroAssembler::RestoreFPRegs(Register location, Register scratch) { | 3360 void MacroAssembler::RestoreFPRegs(Register location, Register scratch) { |
3382 CheckFor32DRegs(scratch); | 3361 CheckFor32DRegs(scratch); |
3383 vldm(ia_w, location, d0, d15); | 3362 vldm(ia_w, location, d0, d15); |
3384 vldm(ia_w, location, d16, d31, ne); | 3363 vldm(ia_w, location, d16, d31, ne); |
3385 add(location, location, Operand(16 * kDoubleSize), LeaveCC, eq); | 3364 add(location, location, Operand(16 * kDoubleSize), LeaveCC, eq); |
3386 } | 3365 } |
3387 | 3366 |
3388 | 3367 |
3389 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialAscii( | 3368 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( |
3390 Register first, | 3369 Register first, Register second, Register scratch1, Register scratch2, |
3391 Register second, | |
3392 Register scratch1, | |
3393 Register scratch2, | |
3394 Label* failure) { | 3370 Label* failure) { |
3395 const int kFlatAsciiStringMask = | 3371 const int kFlatOneByteStringMask = |
3396 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | 3372 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; |
3397 const int kFlatAsciiStringTag = | 3373 const int kFlatOneByteStringTag = |
3398 kStringTag | kOneByteStringTag | kSeqStringTag; | 3374 kStringTag | kOneByteStringTag | kSeqStringTag; |
3399 and_(scratch1, first, Operand(kFlatAsciiStringMask)); | 3375 and_(scratch1, first, Operand(kFlatOneByteStringMask)); |
3400 and_(scratch2, second, Operand(kFlatAsciiStringMask)); | 3376 and_(scratch2, second, Operand(kFlatOneByteStringMask)); |
3401 cmp(scratch1, Operand(kFlatAsciiStringTag)); | 3377 cmp(scratch1, Operand(kFlatOneByteStringTag)); |
3402 // Ignore second test if first test failed. | 3378 // Ignore second test if first test failed. |
3403 cmp(scratch2, Operand(kFlatAsciiStringTag), eq); | 3379 cmp(scratch2, Operand(kFlatOneByteStringTag), eq); |
3404 b(ne, failure); | 3380 b(ne, failure); |
3405 } | 3381 } |
3406 | 3382 |
3407 | 3383 |
3408 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii(Register type, | 3384 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte(Register type, |
3409 Register scratch, | 3385 Register scratch, |
3410 Label* failure) { | 3386 Label* failure) { |
3411 const int kFlatAsciiStringMask = | 3387 const int kFlatOneByteStringMask = |
3412 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | 3388 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; |
3413 const int kFlatAsciiStringTag = | 3389 const int kFlatOneByteStringTag = |
3414 kStringTag | kOneByteStringTag | kSeqStringTag; | 3390 kStringTag | kOneByteStringTag | kSeqStringTag; |
3415 and_(scratch, type, Operand(kFlatAsciiStringMask)); | 3391 and_(scratch, type, Operand(kFlatOneByteStringMask)); |
3416 cmp(scratch, Operand(kFlatAsciiStringTag)); | 3392 cmp(scratch, Operand(kFlatOneByteStringTag)); |
3417 b(ne, failure); | 3393 b(ne, failure); |
3418 } | 3394 } |
3419 | 3395 |
3420 static const int kRegisterPassedArguments = 4; | 3396 static const int kRegisterPassedArguments = 4; |
3421 | 3397 |
3422 | 3398 |
3423 int MacroAssembler::CalculateStackPassedWords(int num_reg_arguments, | 3399 int MacroAssembler::CalculateStackPassedWords(int num_reg_arguments, |
3424 int num_double_arguments) { | 3400 int num_double_arguments) { |
3425 int stack_passed_words = 0; | 3401 int stack_passed_words = 0; |
3426 if (use_eabi_hardfloat()) { | 3402 if (use_eabi_hardfloat()) { |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3820 // If it's external, the length is just ExternalString::kSize. | 3796 // If it's external, the length is just ExternalString::kSize. |
3821 // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). | 3797 // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). |
3822 // External strings are the only ones with the kExternalStringTag bit | 3798 // External strings are the only ones with the kExternalStringTag bit |
3823 // set. | 3799 // set. |
3824 DCHECK_EQ(0, kSeqStringTag & kExternalStringTag); | 3800 DCHECK_EQ(0, kSeqStringTag & kExternalStringTag); |
3825 DCHECK_EQ(0, kConsStringTag & kExternalStringTag); | 3801 DCHECK_EQ(0, kConsStringTag & kExternalStringTag); |
3826 tst(instance_type, Operand(kExternalStringTag)); | 3802 tst(instance_type, Operand(kExternalStringTag)); |
3827 mov(length, Operand(ExternalString::kSize), LeaveCC, ne); | 3803 mov(length, Operand(ExternalString::kSize), LeaveCC, ne); |
3828 b(ne, &is_data_object); | 3804 b(ne, &is_data_object); |
3829 | 3805 |
3830 // Sequential string, either ASCII or UC16. | 3806 // Sequential string, either Latin1 or UC16. |
3831 // For ASCII (char-size of 1) we shift the smi tag away to get the length. | 3807 // For Latin1 (char-size of 1) we shift the smi tag away to get the length. |
3832 // For UC16 (char-size of 2) we just leave the smi tag in place, thereby | 3808 // For UC16 (char-size of 2) we just leave the smi tag in place, thereby |
3833 // getting the length multiplied by 2. | 3809 // getting the length multiplied by 2. |
3834 DCHECK(kOneByteStringTag == 4 && kStringEncodingMask == 4); | 3810 DCHECK(kOneByteStringTag == 4 && kStringEncodingMask == 4); |
3835 DCHECK(kSmiTag == 0 && kSmiTagSize == 1); | 3811 DCHECK(kSmiTag == 0 && kSmiTagSize == 1); |
3836 ldr(ip, FieldMemOperand(value, String::kLengthOffset)); | 3812 ldr(ip, FieldMemOperand(value, String::kLengthOffset)); |
3837 tst(instance_type, Operand(kStringEncodingMask)); | 3813 tst(instance_type, Operand(kStringEncodingMask)); |
3838 mov(ip, Operand(ip, LSR, 1), LeaveCC, ne); | 3814 mov(ip, Operand(ip, LSR, 1), LeaveCC, ne); |
3839 add(length, ip, Operand(SeqString::kHeaderSize + kObjectAlignmentMask)); | 3815 add(length, ip, Operand(SeqString::kHeaderSize + kObjectAlignmentMask)); |
3840 and_(length, length, Operand(~kObjectAlignmentMask)); | 3816 and_(length, length, Operand(~kObjectAlignmentMask)); |
3841 | 3817 |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4106 sub(result, result, Operand(dividend)); | 4082 sub(result, result, Operand(dividend)); |
4107 } | 4083 } |
4108 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 4084 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
4109 add(result, result, Operand(dividend, LSR, 31)); | 4085 add(result, result, Operand(dividend, LSR, 31)); |
4110 } | 4086 } |
4111 | 4087 |
4112 | 4088 |
4113 } } // namespace v8::internal | 4089 } } // namespace v8::internal |
4114 | 4090 |
4115 #endif // V8_TARGET_ARCH_ARM | 4091 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |