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