OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 11174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11185 __ SmiCompare(rbx, Smi::FromInt(String::kMinNonFlatLength)); | 11185 __ SmiCompare(rbx, Smi::FromInt(String::kMinNonFlatLength)); |
11186 __ j(below, &string_add_flat_result); | 11186 __ j(below, &string_add_flat_result); |
11187 // Handle exceptionally long strings in the runtime system. | 11187 // Handle exceptionally long strings in the runtime system. |
11188 ASSERT((String::kMaxLength & 0x80000000) == 0); | 11188 ASSERT((String::kMaxLength & 0x80000000) == 0); |
11189 __ SmiCompare(rbx, Smi::FromInt(String::kMaxLength)); | 11189 __ SmiCompare(rbx, Smi::FromInt(String::kMaxLength)); |
11190 __ j(above, &string_add_runtime); | 11190 __ j(above, &string_add_runtime); |
11191 | 11191 |
11192 // If result is not supposed to be flat, allocate a cons string object. If | 11192 // If result is not supposed to be flat, allocate a cons string object. If |
11193 // both strings are ascii the result is an ascii cons string. | 11193 // both strings are ascii the result is an ascii cons string. |
11194 // rax: first string | 11194 // rax: first string |
11195 // ebx: length of resulting flat string | 11195 // rbx: length of resulting flat string |
11196 // rdx: second string | 11196 // rdx: second string |
11197 // r8: instance type of first string | 11197 // r8: instance type of first string |
11198 // r9: instance type of second string | 11198 // r9: instance type of second string |
11199 Label non_ascii, allocated; | 11199 Label non_ascii, allocated, ascii_data; |
11200 __ movl(rcx, r8); | 11200 __ movl(rcx, r8); |
11201 __ and_(rcx, r9); | 11201 __ and_(rcx, r9); |
11202 ASSERT(kStringEncodingMask == kAsciiStringTag); | 11202 ASSERT(kStringEncodingMask == kAsciiStringTag); |
11203 __ testl(rcx, Immediate(kAsciiStringTag)); | 11203 __ testl(rcx, Immediate(kAsciiStringTag)); |
11204 __ j(zero, &non_ascii); | 11204 __ j(zero, &non_ascii); |
| 11205 __ bind(&ascii_data); |
11205 // Allocate an acsii cons string. | 11206 // Allocate an acsii cons string. |
11206 __ AllocateAsciiConsString(rcx, rdi, no_reg, &string_add_runtime); | 11207 __ AllocateAsciiConsString(rcx, rdi, no_reg, &string_add_runtime); |
11207 __ bind(&allocated); | 11208 __ bind(&allocated); |
11208 // Fill the fields of the cons string. | 11209 // Fill the fields of the cons string. |
11209 __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx); | 11210 __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx); |
11210 __ movq(FieldOperand(rcx, ConsString::kHashFieldOffset), | 11211 __ movq(FieldOperand(rcx, ConsString::kHashFieldOffset), |
11211 Immediate(String::kEmptyHashField)); | 11212 Immediate(String::kEmptyHashField)); |
11212 __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax); | 11213 __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax); |
11213 __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx); | 11214 __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx); |
11214 __ movq(rax, rcx); | 11215 __ movq(rax, rcx); |
11215 __ IncrementCounter(&Counters::string_add_native, 1); | 11216 __ IncrementCounter(&Counters::string_add_native, 1); |
11216 __ ret(2 * kPointerSize); | 11217 __ ret(2 * kPointerSize); |
11217 __ bind(&non_ascii); | 11218 __ bind(&non_ascii); |
| 11219 // At least one of the strings is two-byte. Check whether it happens |
| 11220 // to contain only ascii characters. |
| 11221 // rcx: first instance type AND second instance type. |
| 11222 // r8: first instance type. |
| 11223 // r9: second instance type. |
| 11224 __ testb(rcx, Immediate(kAsciiDataHintMask)); |
| 11225 __ j(not_zero, &ascii_data); |
| 11226 __ xor_(r8, r9); |
| 11227 ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0); |
| 11228 __ andb(r8, Immediate(kAsciiStringTag | kAsciiDataHintTag)); |
| 11229 __ cmpb(r8, Immediate(kAsciiStringTag | kAsciiDataHintTag)); |
| 11230 __ j(equal, &ascii_data); |
11218 // Allocate a two byte cons string. | 11231 // Allocate a two byte cons string. |
11219 __ AllocateConsString(rcx, rdi, no_reg, &string_add_runtime); | 11232 __ AllocateConsString(rcx, rdi, no_reg, &string_add_runtime); |
11220 __ jmp(&allocated); | 11233 __ jmp(&allocated); |
11221 | 11234 |
11222 // Handle creating a flat result. First check that both strings are not | 11235 // Handle creating a flat result. First check that both strings are not |
11223 // external strings. | 11236 // external strings. |
11224 // rax: first string | 11237 // rax: first string |
11225 // ebx: length of resulting flat string as smi | 11238 // rbx: length of resulting flat string as smi |
11226 // rdx: second string | 11239 // rdx: second string |
11227 // r8: instance type of first string | 11240 // r8: instance type of first string |
11228 // r9: instance type of first string | 11241 // r9: instance type of first string |
11229 __ bind(&string_add_flat_result); | 11242 __ bind(&string_add_flat_result); |
11230 __ SmiToInteger32(rbx, rbx); | 11243 __ SmiToInteger32(rbx, rbx); |
11231 __ movl(rcx, r8); | 11244 __ movl(rcx, r8); |
11232 __ and_(rcx, Immediate(kStringRepresentationMask)); | 11245 __ and_(rcx, Immediate(kStringRepresentationMask)); |
11233 __ cmpl(rcx, Immediate(kExternalStringTag)); | 11246 __ cmpl(rcx, Immediate(kExternalStringTag)); |
11234 __ j(equal, &string_add_runtime); | 11247 __ j(equal, &string_add_runtime); |
11235 __ movl(rcx, r9); | 11248 __ movl(rcx, r9); |
11236 __ and_(rcx, Immediate(kStringRepresentationMask)); | 11249 __ and_(rcx, Immediate(kStringRepresentationMask)); |
11237 __ cmpl(rcx, Immediate(kExternalStringTag)); | 11250 __ cmpl(rcx, Immediate(kExternalStringTag)); |
11238 __ j(equal, &string_add_runtime); | 11251 __ j(equal, &string_add_runtime); |
11239 // Now check if both strings are ascii strings. | 11252 // Now check if both strings are ascii strings. |
11240 // rax: first string | 11253 // rax: first string |
11241 // ebx: length of resulting flat string | 11254 // rbx: length of resulting flat string |
11242 // rdx: second string | 11255 // rdx: second string |
11243 // r8: instance type of first string | 11256 // r8: instance type of first string |
11244 // r9: instance type of second string | 11257 // r9: instance type of second string |
11245 Label non_ascii_string_add_flat_result; | 11258 Label non_ascii_string_add_flat_result; |
11246 ASSERT(kStringEncodingMask == kAsciiStringTag); | 11259 ASSERT(kStringEncodingMask == kAsciiStringTag); |
11247 __ testl(r8, Immediate(kAsciiStringTag)); | 11260 __ testl(r8, Immediate(kAsciiStringTag)); |
11248 __ j(zero, &non_ascii_string_add_flat_result); | 11261 __ j(zero, &non_ascii_string_add_flat_result); |
11249 __ testl(r9, Immediate(kAsciiStringTag)); | 11262 __ testl(r9, Immediate(kAsciiStringTag)); |
11250 __ j(zero, &string_add_runtime); | 11263 __ j(zero, &string_add_runtime); |
11251 | 11264 |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11930 } | 11943 } |
11931 | 11944 |
11932 #endif | 11945 #endif |
11933 | 11946 |
11934 | 11947 |
11935 #undef __ | 11948 #undef __ |
11936 | 11949 |
11937 } } // namespace v8::internal | 11950 } } // namespace v8::internal |
11938 | 11951 |
11939 #endif // V8_TARGET_ARCH_X64 | 11952 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |