| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 5509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5520 // ebx: length of first string as a smi | 5520 // ebx: length of first string as a smi |
| 5521 // ecx: length of second string as a smi | 5521 // ecx: length of second string as a smi |
| 5522 // edx: second string | 5522 // edx: second string |
| 5523 // Look at the length of the result of adding the two strings. | 5523 // Look at the length of the result of adding the two strings. |
| 5524 Label string_add_flat_result, longer_than_two; | 5524 Label string_add_flat_result, longer_than_two; |
| 5525 __ bind(&both_not_zero_length); | 5525 __ bind(&both_not_zero_length); |
| 5526 __ add(ebx, Operand(ecx)); | 5526 __ add(ebx, Operand(ecx)); |
| 5527 STATIC_ASSERT(Smi::kMaxValue == String::kMaxLength); | 5527 STATIC_ASSERT(Smi::kMaxValue == String::kMaxLength); |
| 5528 // Handle exceptionally long strings in the runtime system. | 5528 // Handle exceptionally long strings in the runtime system. |
| 5529 __ j(overflow, &string_add_runtime); | 5529 __ j(overflow, &string_add_runtime); |
| 5530 // Use the runtime system when adding two one character strings, as it | 5530 // Use the symbol table when adding two one character strings, as it |
| 5531 // contains optimizations for this specific case using the symbol table. | 5531 // helps later optimizations to return a symbol here. |
| 5532 __ cmp(Operand(ebx), Immediate(Smi::FromInt(2))); | 5532 __ cmp(Operand(ebx), Immediate(Smi::FromInt(2))); |
| 5533 __ j(not_equal, &longer_than_two); | 5533 __ j(not_equal, &longer_than_two); |
| 5534 | 5534 |
| 5535 // Check that both strings are non-external ascii strings. | 5535 // Check that both strings are non-external ascii strings. |
| 5536 __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx, | 5536 __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx, |
| 5537 &string_add_runtime); | 5537 &string_add_runtime); |
| 5538 | 5538 |
| 5539 // Get the two characters forming the new string. | 5539 // Get the two characters forming the new string. |
| 5540 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize)); | 5540 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize)); |
| 5541 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize)); | 5541 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize)); |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5938 STATIC_ASSERT(SymbolTable::kEntrySize == 1); | 5938 STATIC_ASSERT(SymbolTable::kEntrySize == 1); |
| 5939 __ mov(candidate, | 5939 __ mov(candidate, |
| 5940 FieldOperand(symbol_table, | 5940 FieldOperand(symbol_table, |
| 5941 scratch, | 5941 scratch, |
| 5942 times_pointer_size, | 5942 times_pointer_size, |
| 5943 SymbolTable::kElementsStartOffset)); | 5943 SymbolTable::kElementsStartOffset)); |
| 5944 | 5944 |
| 5945 // If entry is undefined no string with this hash can be found. | 5945 // If entry is undefined no string with this hash can be found. |
| 5946 __ cmp(candidate, FACTORY->undefined_value()); | 5946 __ cmp(candidate, FACTORY->undefined_value()); |
| 5947 __ j(equal, not_found); | 5947 __ j(equal, not_found); |
| 5948 __ cmp(candidate, FACTORY->null_value()); |
| 5949 __ j(equal, &next_probe[i]); |
| 5948 | 5950 |
| 5949 // If length is not 2 the string is not a candidate. | 5951 // If length is not 2 the string is not a candidate. |
| 5950 __ cmp(FieldOperand(candidate, String::kLengthOffset), | 5952 __ cmp(FieldOperand(candidate, String::kLengthOffset), |
| 5951 Immediate(Smi::FromInt(2))); | 5953 Immediate(Smi::FromInt(2))); |
| 5952 __ j(not_equal, &next_probe[i]); | 5954 __ j(not_equal, &next_probe[i]); |
| 5953 | 5955 |
| 5954 // As we are out of registers save the mask on the stack and use that | 5956 // As we are out of registers save the mask on the stack and use that |
| 5955 // register as a temporary. | 5957 // register as a temporary. |
| 5956 __ push(mask); | 5958 __ push(mask); |
| 5957 Register temp = mask; | 5959 Register temp = mask; |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6306 __ push(ecx); | 6308 __ push(ecx); |
| 6307 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); | 6309 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); |
| 6308 | 6310 |
| 6309 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 6311 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 6310 // tagged as a small integer. | 6312 // tagged as a small integer. |
| 6311 __ bind(&runtime); | 6313 __ bind(&runtime); |
| 6312 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 6314 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 6313 } | 6315 } |
| 6314 | 6316 |
| 6315 | 6317 |
| 6316 void StringCharAtStub::Generate(MacroAssembler* masm) { | |
| 6317 // Expects two arguments (object, index) on the stack: | |
| 6318 | |
| 6319 // Stack frame on entry. | |
| 6320 // esp[0]: return address | |
| 6321 // esp[4]: index | |
| 6322 // esp[8]: object | |
| 6323 | |
| 6324 Register object = ebx; | |
| 6325 Register index = eax; | |
| 6326 Register scratch1 = ecx; | |
| 6327 Register scratch2 = edx; | |
| 6328 Register result = eax; | |
| 6329 | |
| 6330 __ pop(scratch1); // Return address. | |
| 6331 __ pop(index); | |
| 6332 __ pop(object); | |
| 6333 __ push(scratch1); | |
| 6334 | |
| 6335 Label need_conversion; | |
| 6336 Label index_out_of_range; | |
| 6337 Label done; | |
| 6338 StringCharAtGenerator generator(object, | |
| 6339 index, | |
| 6340 scratch1, | |
| 6341 scratch2, | |
| 6342 result, | |
| 6343 &need_conversion, | |
| 6344 &need_conversion, | |
| 6345 &index_out_of_range, | |
| 6346 STRING_INDEX_IS_NUMBER); | |
| 6347 generator.GenerateFast(masm); | |
| 6348 __ jmp(&done); | |
| 6349 | |
| 6350 __ bind(&index_out_of_range); | |
| 6351 // When the index is out of range, the spec requires us to return | |
| 6352 // the empty string. | |
| 6353 __ Set(result, Immediate(FACTORY->empty_string())); | |
| 6354 __ jmp(&done); | |
| 6355 | |
| 6356 __ bind(&need_conversion); | |
| 6357 // Move smi zero into the result register, which will trigger | |
| 6358 // conversion. | |
| 6359 __ Set(result, Immediate(Smi::FromInt(0))); | |
| 6360 __ jmp(&done); | |
| 6361 | |
| 6362 StubRuntimeCallHelper call_helper; | |
| 6363 generator.GenerateSlow(masm, call_helper); | |
| 6364 | |
| 6365 __ bind(&done); | |
| 6366 __ ret(0); | |
| 6367 } | |
| 6368 | |
| 6369 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { | 6318 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { |
| 6370 ASSERT(state_ == CompareIC::SMIS); | 6319 ASSERT(state_ == CompareIC::SMIS); |
| 6371 NearLabel miss; | 6320 NearLabel miss; |
| 6372 __ mov(ecx, Operand(edx)); | 6321 __ mov(ecx, Operand(edx)); |
| 6373 __ or_(ecx, Operand(eax)); | 6322 __ or_(ecx, Operand(eax)); |
| 6374 __ test(ecx, Immediate(kSmiTagMask)); | 6323 __ test(ecx, Immediate(kSmiTagMask)); |
| 6375 __ j(not_zero, &miss, not_taken); | 6324 __ j(not_zero, &miss, not_taken); |
| 6376 | 6325 |
| 6377 if (GetCondition() == equal) { | 6326 if (GetCondition() == equal) { |
| 6378 // For equality we do not care about the sign of the result. | 6327 // For equality we do not care about the sign of the result. |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6497 // Do a tail call to the rewritten stub. | 6446 // Do a tail call to the rewritten stub. |
| 6498 __ jmp(Operand(edi)); | 6447 __ jmp(Operand(edi)); |
| 6499 } | 6448 } |
| 6500 | 6449 |
| 6501 | 6450 |
| 6502 #undef __ | 6451 #undef __ |
| 6503 | 6452 |
| 6504 } } // namespace v8::internal | 6453 } } // namespace v8::internal |
| 6505 | 6454 |
| 6506 #endif // V8_TARGET_ARCH_IA32 | 6455 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |