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 7614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7625 __ push(edx); | 7625 __ push(edx); |
7626 } else { | 7626 } else { |
7627 __ push(edx); | 7627 __ push(edx); |
7628 __ push(eax); | 7628 __ push(eax); |
7629 } | 7629 } |
7630 __ push(ecx); | 7630 __ push(ecx); |
7631 } | 7631 } |
7632 switch (op_) { | 7632 switch (op_) { |
7633 case Token::ADD: { | 7633 case Token::ADD: { |
7634 // Test for string arguments before calling runtime. | 7634 // Test for string arguments before calling runtime. |
7635 Label not_strings, not_string1, string1; | 7635 Label not_strings, not_string1, string1, string1_smi2; |
7636 Result answer; | 7636 Result answer; |
7637 __ test(edx, Immediate(kSmiTagMask)); | 7637 __ test(edx, Immediate(kSmiTagMask)); |
7638 __ j(zero, ¬_string1); | 7638 __ j(zero, ¬_string1); |
7639 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, ecx); | 7639 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, ecx); |
7640 __ j(above_equal, ¬_string1); | 7640 __ j(above_equal, ¬_string1); |
7641 | 7641 |
7642 // First argument is a string, test second. | 7642 // First argument is a string, test second. |
7643 __ test(eax, Immediate(kSmiTagMask)); | 7643 __ test(eax, Immediate(kSmiTagMask)); |
7644 __ j(zero, &string1); | 7644 __ j(zero, &string1_smi2); |
7645 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx); | 7645 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx); |
7646 __ j(above_equal, &string1); | 7646 __ j(above_equal, &string1); |
7647 | 7647 |
7648 // First and second argument are strings. Jump to the string add stub. | 7648 // First and second argument are strings. Jump to the string add stub. |
7649 StringAddStub stub(NO_STRING_CHECK_IN_STUB); | 7649 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB); |
7650 __ TailCallStub(&stub); | 7650 __ TailCallStub(&string_add_stub); |
7651 | 7651 |
7652 // Only first argument is a string. | 7652 __ bind(&string1_smi2); |
| 7653 // First argument is a string, second is a smi. Try to lookup the number |
| 7654 // string for the smi in the number string cache. |
| 7655 // Load the number string cache. |
| 7656 ExternalReference roots_address = ExternalReference::roots_address(); |
| 7657 __ mov(ecx, Immediate(Heap::kNumberStringCacheRootIndex)); |
| 7658 __ mov(ebx, |
| 7659 Operand::StaticArray(ecx, times_pointer_size, roots_address)); |
| 7660 // Make the hash mask from the length of the number string cache. It |
| 7661 // contains two elements (number and string) for each cache entry. |
| 7662 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); |
| 7663 __ shr(ecx, 1); // Divide length by two (length is not a smi). |
| 7664 __ sub(Operand(ecx), Immediate(1)); // Make mask. |
| 7665 // Calculate the entry in the number string cache. The hash value in the |
| 7666 // number string cache for smis is just the smi value. |
| 7667 __ mov(edi, eax); |
| 7668 __ SmiUntag(edi); |
| 7669 __ and_(edi, Operand(ecx)); |
| 7670 // Check if the entry is the smi we are looking for. |
| 7671 __ cmp(eax, |
| 7672 FieldOperand(ebx, |
| 7673 edi, |
| 7674 times_twice_pointer_size, |
| 7675 FixedArray::kHeaderSize)); |
| 7676 __ IncrementCounter(equal, &Counters::string_plus_smi_hit, 1); |
| 7677 __ IncrementCounter(not_equal, &Counters::string_plus_smi_miss, 1); |
| 7678 __ j(not_equal, &string1); |
| 7679 |
| 7680 // Get the string from the cache and call the string add stub to make the |
| 7681 // result. |
| 7682 __ mov(edi, |
| 7683 FieldOperand(ebx, |
| 7684 edi, |
| 7685 times_twice_pointer_size, |
| 7686 FixedArray::kHeaderSize + kPointerSize)); |
| 7687 __ EnterInternalFrame(); |
| 7688 __ push(edx); // Original first argument. |
| 7689 __ push(edi); // Number to string result for second argument. |
| 7690 __ CallStub(&string_add_stub); |
| 7691 __ LeaveInternalFrame(); |
| 7692 __ ret(2 * kPointerSize); |
| 7693 |
7653 __ bind(&string1); | 7694 __ bind(&string1); |
7654 __ InvokeBuiltin( | 7695 __ InvokeBuiltin( |
7655 HasArgsReversed() ? | 7696 HasArgsReversed() ? |
7656 Builtins::STRING_ADD_RIGHT : | 7697 Builtins::STRING_ADD_RIGHT : |
7657 Builtins::STRING_ADD_LEFT, | 7698 Builtins::STRING_ADD_LEFT, |
7658 JUMP_FUNCTION); | 7699 JUMP_FUNCTION); |
7659 | 7700 |
7660 // First argument was not a string, test second. | 7701 // First argument was not a string, test second. |
7661 __ bind(¬_string1); | 7702 __ bind(¬_string1); |
7662 __ test(eax, Immediate(kSmiTagMask)); | 7703 __ test(eax, Immediate(kSmiTagMask)); |
(...skipping 2446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10109 | 10150 |
10110 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 10151 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
10111 // tagged as a small integer. | 10152 // tagged as a small integer. |
10112 __ bind(&runtime); | 10153 __ bind(&runtime); |
10113 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); | 10154 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); |
10114 } | 10155 } |
10115 | 10156 |
10116 #undef __ | 10157 #undef __ |
10117 | 10158 |
10118 } } // namespace v8::internal | 10159 } } // namespace v8::internal |
OLD | NEW |