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 5932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5943 // push. | 5943 // push. |
5944 Label slow_case; | 5944 Label slow_case; |
5945 Label exit; | 5945 Label exit; |
5946 StringHelper::GenerateFastCharCodeAt(masm_, | 5946 StringHelper::GenerateFastCharCodeAt(masm_, |
5947 object.reg(), | 5947 object.reg(), |
5948 index.reg(), | 5948 index.reg(), |
5949 scratch.reg(), | 5949 scratch.reg(), |
5950 result.reg(), | 5950 result.reg(), |
5951 &slow_case, | 5951 &slow_case, |
5952 &slow_case, | 5952 &slow_case, |
| 5953 &slow_case, |
5953 &slow_case); | 5954 &slow_case); |
5954 __ jmp(&exit); | 5955 __ jmp(&exit); |
5955 | 5956 |
5956 __ bind(&slow_case); | 5957 __ bind(&slow_case); |
5957 // Move the undefined value into the result register, which will | 5958 // Move the undefined value into the result register, which will |
5958 // trigger the slow case. | 5959 // trigger the slow case. |
5959 __ Set(result.reg(), Immediate(Factory::undefined_value())); | 5960 __ Set(result.reg(), Immediate(Factory::undefined_value())); |
5960 | 5961 |
5961 __ bind(&exit); | 5962 __ bind(&exit); |
5962 frame_->Push(&result); | 5963 frame_->Push(&result); |
(...skipping 6081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12044 return name_; | 12045 return name_; |
12045 } | 12046 } |
12046 | 12047 |
12047 | 12048 |
12048 void StringHelper::GenerateFastCharCodeAt(MacroAssembler* masm, | 12049 void StringHelper::GenerateFastCharCodeAt(MacroAssembler* masm, |
12049 Register object, | 12050 Register object, |
12050 Register index, | 12051 Register index, |
12051 Register scratch, | 12052 Register scratch, |
12052 Register result, | 12053 Register result, |
12053 Label* receiver_not_string, | 12054 Label* receiver_not_string, |
12054 Label* index_not_positive_smi, | 12055 Label* index_not_smi, |
| 12056 Label* index_out_of_range, |
12055 Label* slow_case) { | 12057 Label* slow_case) { |
12056 Label not_a_flat_string; | 12058 Label not_a_flat_string; |
12057 Label try_again_with_new_string; | 12059 Label try_again_with_new_string; |
12058 Label ascii_string; | 12060 Label ascii_string; |
12059 Label got_char_code; | 12061 Label got_char_code; |
12060 | 12062 |
12061 // If the receiver is a smi trigger the non-string case. | 12063 // If the receiver is a smi trigger the non-string case. |
12062 ASSERT(kSmiTag == 0); | 12064 ASSERT(kSmiTag == 0); |
12063 __ test(object, Immediate(kSmiTagMask)); | 12065 __ test(object, Immediate(kSmiTagMask)); |
12064 __ j(zero, receiver_not_string); | 12066 __ j(zero, receiver_not_string); |
12065 | 12067 |
12066 // Fetch the instance type of the receiver into result register. | 12068 // Fetch the instance type of the receiver into result register. |
12067 __ mov(result, FieldOperand(object, HeapObject::kMapOffset)); | 12069 __ mov(result, FieldOperand(object, HeapObject::kMapOffset)); |
12068 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); | 12070 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); |
12069 // If the receiver is not a string trigger the non-string case. | 12071 // If the receiver is not a string trigger the non-string case. |
12070 __ test(result, Immediate(kIsNotStringMask)); | 12072 __ test(result, Immediate(kIsNotStringMask)); |
12071 __ j(not_zero, receiver_not_string); | 12073 __ j(not_zero, receiver_not_string); |
12072 | 12074 |
12073 // If the index is negative or non-smi trigger the non-positive-smi | 12075 // If the index is non-smi trigger the non-smi case. |
12074 // case. | |
12075 ASSERT(kSmiTag == 0); | 12076 ASSERT(kSmiTag == 0); |
12076 __ test(index, Immediate(kSmiTagMask | kSmiSignMask)); | 12077 __ test(index, Immediate(kSmiTagMask)); |
12077 __ j(not_zero, index_not_positive_smi); | 12078 __ j(not_zero, index_not_smi); |
12078 | 12079 |
12079 // Put untagged index into scratch register. | 12080 // Put untagged index into scratch register. |
12080 __ mov(scratch, index); | 12081 __ mov(scratch, index); |
12081 __ SmiUntag(scratch); | 12082 __ SmiUntag(scratch); |
12082 | 12083 |
12083 // Check for index out of range. | 12084 // Check for index out of range. |
12084 __ cmp(scratch, FieldOperand(object, String::kLengthOffset)); | 12085 __ cmp(scratch, FieldOperand(object, String::kLengthOffset)); |
12085 __ j(greater_equal, slow_case); | 12086 __ j(above_equal, index_out_of_range); |
12086 | 12087 |
12087 __ bind(&try_again_with_new_string); | 12088 __ bind(&try_again_with_new_string); |
12088 // ----------- S t a t e ------------- | 12089 // ----------- S t a t e ------------- |
12089 // -- object : string to access | 12090 // -- object : string to access |
12090 // -- result : instance type of the string | 12091 // -- result : instance type of the string |
12091 // -- scratch : positive smi index < length | 12092 // -- scratch : non-negative index < length |
12092 // ----------------------------------- | 12093 // ----------------------------------- |
12093 | 12094 |
12094 // We need special handling for non-flat strings. | 12095 // We need special handling for non-flat strings. |
12095 ASSERT(kSeqStringTag == 0); | 12096 ASSERT(kSeqStringTag == 0); |
12096 __ test(result, Immediate(kStringRepresentationMask)); | 12097 __ test(result, Immediate(kStringRepresentationMask)); |
12097 __ j(not_zero, ¬_a_flat_string); | 12098 __ j(not_zero, ¬_a_flat_string); |
12098 | 12099 |
12099 // Check for 1-byte or 2-byte string. | 12100 // Check for 1-byte or 2-byte string. |
12100 ASSERT(kAsciiStringTag != 0); | 12101 ASSERT(kAsciiStringTag != 0); |
12101 __ test(result, Immediate(kStringEncodingMask)); | 12102 __ test(result, Immediate(kStringEncodingMask)); |
12102 __ j(not_zero, &ascii_string); | 12103 __ j(not_zero, &ascii_string); |
12103 | 12104 |
12104 // 2-byte string. | 12105 // 2-byte string. |
12105 // Load the 2-byte character code into the temp register. | 12106 // Load the 2-byte character code into the result register. |
12106 __ movzx_w(result, FieldOperand(object, | 12107 __ movzx_w(result, FieldOperand(object, |
12107 scratch, times_2, | 12108 scratch, times_2, |
12108 SeqTwoByteString::kHeaderSize)); | 12109 SeqTwoByteString::kHeaderSize)); |
12109 __ jmp(&got_char_code); | 12110 __ jmp(&got_char_code); |
12110 | 12111 |
12111 // Handle non-flat strings. | 12112 // Handle non-flat strings. |
12112 __ bind(¬_a_flat_string); | 12113 __ bind(¬_a_flat_string); |
12113 __ and_(result, kStringRepresentationMask); | 12114 __ and_(result, kStringRepresentationMask); |
12114 __ cmp(result, kConsStringTag); | 12115 __ cmp(result, kConsStringTag); |
12115 __ j(not_equal, slow_case); | 12116 __ j(not_equal, slow_case); |
12116 | 12117 |
12117 // ConsString. | 12118 // ConsString. |
12118 // Check whether the right hand side is the empty string (i.e. if | 12119 // Check whether the right hand side is the empty string (i.e. if |
12119 // this is really a flat string in a cons string). If that is not | 12120 // this is really a flat string in a cons string). If that is not |
12120 // the case we would rather go to the runtime system now to flatten | 12121 // the case we would rather go to the runtime system now to flatten |
12121 // the string. | 12122 // the string. |
12122 __ mov(result, FieldOperand(object, ConsString::kSecondOffset)); | 12123 __ mov(result, FieldOperand(object, ConsString::kSecondOffset)); |
12123 __ cmp(Operand(result), Factory::empty_string()); | 12124 __ cmp(Operand(result), Factory::empty_string()); |
12124 __ j(not_equal, slow_case); | 12125 __ j(not_equal, slow_case); |
12125 // Get the first of the two strings and load its instance type. | 12126 // Get the first of the two strings and load its instance type. |
12126 __ mov(object, FieldOperand(object, ConsString::kFirstOffset)); | 12127 __ mov(object, FieldOperand(object, ConsString::kFirstOffset)); |
12127 __ mov(result, FieldOperand(object, HeapObject::kMapOffset)); | 12128 __ mov(result, FieldOperand(object, HeapObject::kMapOffset)); |
12128 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); | 12129 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); |
12129 __ jmp(&try_again_with_new_string); | 12130 __ jmp(&try_again_with_new_string); |
12130 | 12131 |
12131 // ASCII string. | 12132 // ASCII string. |
12132 __ bind(&ascii_string); | 12133 __ bind(&ascii_string); |
12133 // Load the byte into the temp register. | 12134 // Load the byte into the result register. |
12134 __ movzx_b(result, FieldOperand(object, | 12135 __ movzx_b(result, FieldOperand(object, |
12135 scratch, times_1, | 12136 scratch, times_1, |
12136 SeqAsciiString::kHeaderSize)); | 12137 SeqAsciiString::kHeaderSize)); |
12137 __ bind(&got_char_code); | 12138 __ bind(&got_char_code); |
12138 __ SmiTag(result); | 12139 __ SmiTag(result); |
12139 } | 12140 } |
12140 | 12141 |
12141 | 12142 |
12142 void StringHelper::GenerateCharFromCode(MacroAssembler* masm, | 12143 void StringHelper::GenerateCharFromCode(MacroAssembler* masm, |
12143 Register code, | 12144 Register code, |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12927 | 12928 |
12928 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 12929 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
12929 // tagged as a small integer. | 12930 // tagged as a small integer. |
12930 __ bind(&runtime); | 12931 __ bind(&runtime); |
12931 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 12932 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
12932 } | 12933 } |
12933 | 12934 |
12934 #undef __ | 12935 #undef __ |
12935 | 12936 |
12936 } } // namespace v8::internal | 12937 } } // namespace v8::internal |
OLD | NEW |