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 6083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6094 __ mov(r0, Operand(1)); // Non-zero indicates not equal. | 6094 __ mov(r0, Operand(1)); // Non-zero indicates not equal. |
6095 __ mov(pc, Operand(lr)); // Return. | 6095 __ mov(pc, Operand(lr)); // Return. |
6096 } | 6096 } |
6097 | 6097 |
6098 | 6098 |
6099 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, | 6099 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, |
6100 Register object, | 6100 Register object, |
6101 Register result, | 6101 Register result, |
6102 Register scratch1, | 6102 Register scratch1, |
6103 Register scratch2, | 6103 Register scratch2, |
| 6104 Register scratch3, |
6104 bool object_is_smi, | 6105 bool object_is_smi, |
6105 Label* not_found) { | 6106 Label* not_found) { |
6106 // Currently only lookup for smis. Check for smi if object is not known to be | |
6107 // a smi. | |
6108 if (!object_is_smi) { | |
6109 ASSERT(kSmiTag == 0); | |
6110 __ tst(object, Operand(kSmiTagMask)); | |
6111 __ b(ne, not_found); | |
6112 } | |
6113 | |
6114 // Use of registers. Register result is used as a temporary. | 6107 // Use of registers. Register result is used as a temporary. |
6115 Register number_string_cache = result; | 6108 Register number_string_cache = result; |
6116 Register mask = scratch1; | 6109 Register mask = scratch3; |
6117 Register scratch = scratch2; | |
6118 | 6110 |
6119 // Load the number string cache. | 6111 // Load the number string cache. |
6120 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); | 6112 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); |
6121 | 6113 |
6122 // Make the hash mask from the length of the number string cache. It | 6114 // Make the hash mask from the length of the number string cache. It |
6123 // contains two elements (number and string) for each cache entry. | 6115 // contains two elements (number and string) for each cache entry. |
6124 __ ldr(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset)); | 6116 __ ldr(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset)); |
6125 // Divide length by two (length is not a smi). | 6117 // Divide length by two (length is not a smi). |
6126 __ mov(mask, Operand(mask, ASR, 1)); | 6118 __ mov(mask, Operand(mask, ASR, 1)); |
6127 __ sub(mask, mask, Operand(1)); // Make mask. | 6119 __ sub(mask, mask, Operand(1)); // Make mask. |
6128 | 6120 |
6129 // Calculate the entry in the number string cache. The hash value in the | 6121 // Calculate the entry in the number string cache. The hash value in the |
6130 // number string cache for smis is just the smi value. | 6122 // number string cache for smis is just the smi value, and the hash for |
| 6123 // doubles is the xor of the upper and lower words. See |
| 6124 // Heap::GetNumberStringCache. |
| 6125 Label is_smi; |
| 6126 Label load_result_from_cache; |
| 6127 if (!object_is_smi) { |
| 6128 __ BranchOnSmi(object, &is_smi); |
| 6129 if (CpuFeatures::IsSupported(VFP3)) { |
| 6130 CpuFeatures::Scope scope(VFP3); |
| 6131 __ CheckMap(object, |
| 6132 scratch1, |
| 6133 Factory::heap_number_map(), |
| 6134 not_found, |
| 6135 true); |
| 6136 |
| 6137 ASSERT_EQ(8, kDoubleSize); |
| 6138 __ add(scratch1, |
| 6139 object, |
| 6140 Operand(HeapNumber::kValueOffset - kHeapObjectTag)); |
| 6141 __ ldm(ia, scratch1, scratch1.bit() | scratch2.bit()); |
| 6142 __ eor(scratch1, scratch1, Operand(scratch2)); |
| 6143 __ and_(scratch1, scratch1, Operand(mask)); |
| 6144 |
| 6145 // Calculate address of entry in string cache: each entry consists |
| 6146 // of two pointer sized fields. |
| 6147 __ add(scratch1, |
| 6148 number_string_cache, |
| 6149 Operand(scratch1, LSL, kPointerSizeLog2 + 1)); |
| 6150 |
| 6151 Register probe = mask; |
| 6152 __ ldr(probe, |
| 6153 FieldMemOperand(scratch1, FixedArray::kHeaderSize)); |
| 6154 __ BranchOnSmi(probe, not_found); |
| 6155 __ sub(scratch2, object, Operand(kHeapObjectTag)); |
| 6156 __ vldr(d0, scratch2, HeapNumber::kValueOffset); |
| 6157 __ sub(probe, probe, Operand(kHeapObjectTag)); |
| 6158 __ vldr(d1, probe, HeapNumber::kValueOffset); |
| 6159 __ vcmp(d0, d1); |
| 6160 __ b(ne, not_found); // The cache did not contain this value. |
| 6161 __ b(&load_result_from_cache); |
| 6162 } else { |
| 6163 __ b(not_found); |
| 6164 } |
| 6165 } |
| 6166 |
| 6167 __ bind(&is_smi); |
| 6168 Register scratch = scratch1; |
6131 __ and_(scratch, mask, Operand(object, ASR, 1)); | 6169 __ and_(scratch, mask, Operand(object, ASR, 1)); |
6132 | |
6133 // Calculate address of entry in string cache: each entry consists | 6170 // Calculate address of entry in string cache: each entry consists |
6134 // of two pointer sized fields. | 6171 // of two pointer sized fields. |
6135 __ add(scratch, | 6172 __ add(scratch, |
6136 number_string_cache, | 6173 number_string_cache, |
6137 Operand(scratch, LSL, kPointerSizeLog2 + 1)); | 6174 Operand(scratch, LSL, kPointerSizeLog2 + 1)); |
6138 | 6175 |
6139 // Check if the entry is the smi we are looking for. | 6176 // Check if the entry is the smi we are looking for. |
6140 Register object1 = scratch1; | 6177 Register probe = mask; |
6141 __ ldr(object1, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | 6178 __ ldr(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
6142 __ cmp(object, object1); | 6179 __ cmp(object, probe); |
6143 __ b(ne, not_found); | 6180 __ b(ne, not_found); |
6144 | 6181 |
6145 // Get the result from the cache. | 6182 // Get the result from the cache. |
| 6183 __ bind(&load_result_from_cache); |
6146 __ ldr(result, | 6184 __ ldr(result, |
6147 FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); | 6185 FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); |
6148 | |
6149 __ IncrementCounter(&Counters::number_to_string_native, | 6186 __ IncrementCounter(&Counters::number_to_string_native, |
6150 1, | 6187 1, |
6151 scratch1, | 6188 scratch1, |
6152 scratch2); | 6189 scratch2); |
6153 } | 6190 } |
6154 | 6191 |
6155 | 6192 |
6156 void NumberToStringStub::Generate(MacroAssembler* masm) { | 6193 void NumberToStringStub::Generate(MacroAssembler* masm) { |
6157 Label runtime; | 6194 Label runtime; |
6158 | 6195 |
6159 __ ldr(r1, MemOperand(sp, 0)); | 6196 __ ldr(r1, MemOperand(sp, 0)); |
6160 | 6197 |
6161 // Generate code to lookup number in the number string cache. | 6198 // Generate code to lookup number in the number string cache. |
6162 GenerateLookupNumberStringCache(masm, r1, r0, r2, r3, false, &runtime); | 6199 GenerateLookupNumberStringCache(masm, r1, r0, r2, r3, r4, false, &runtime); |
6163 __ add(sp, sp, Operand(1 * kPointerSize)); | 6200 __ add(sp, sp, Operand(1 * kPointerSize)); |
6164 __ Ret(); | 6201 __ Ret(); |
6165 | 6202 |
6166 __ bind(&runtime); | 6203 __ bind(&runtime); |
6167 // Handle number to string in the runtime system if not found in the cache. | 6204 // Handle number to string in the runtime system if not found in the cache. |
6168 __ TailCallRuntime(Runtime::kNumberToString, 1, 1); | 6205 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); |
6169 } | 6206 } |
6170 | 6207 |
6171 | 6208 |
6172 // On entry r0 (rhs) and r1 (lhs) are the values to be compared. | 6209 // On entry r0 (rhs) and r1 (lhs) are the values to be compared. |
6173 // On exit r0 is 0, positive or negative to indicate the result of | 6210 // On exit r0 is 0, positive or negative to indicate the result of |
6174 // the comparison. | 6211 // the comparison. |
6175 void CompareStub::Generate(MacroAssembler* masm) { | 6212 void CompareStub::Generate(MacroAssembler* masm) { |
6176 Label slow; // Call builtin. | 6213 Label slow; // Call builtin. |
6177 Label not_smis, both_loaded_as_doubles, lhs_not_nan; | 6214 Label not_smis, both_loaded_as_doubles, lhs_not_nan; |
6178 | 6215 |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6551 __ b(ge, &string1); | 6588 __ b(ge, &string1); |
6552 | 6589 |
6553 // First and second argument are strings. | 6590 // First and second argument are strings. |
6554 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB); | 6591 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB); |
6555 __ TailCallStub(&string_add_stub); | 6592 __ TailCallStub(&string_add_stub); |
6556 | 6593 |
6557 __ bind(&string1_smi2); | 6594 __ bind(&string1_smi2); |
6558 // First argument is a string, second is a smi. Try to lookup the number | 6595 // First argument is a string, second is a smi. Try to lookup the number |
6559 // string for the smi in the number string cache. | 6596 // string for the smi in the number string cache. |
6560 NumberToStringStub::GenerateLookupNumberStringCache( | 6597 NumberToStringStub::GenerateLookupNumberStringCache( |
6561 masm, r0, r2, r4, r5, true, &string1); | 6598 masm, r0, r2, r4, r5, r6, true, &string1); |
6562 | 6599 |
6563 // Replace second argument on stack and tailcall string add stub to make | 6600 // Replace second argument on stack and tailcall string add stub to make |
6564 // the result. | 6601 // the result. |
6565 __ str(r2, MemOperand(sp, 0)); | 6602 __ str(r2, MemOperand(sp, 0)); |
6566 __ TailCallStub(&string_add_stub); | 6603 __ TailCallStub(&string_add_stub); |
6567 | 6604 |
6568 // Only first argument is a string. | 6605 // Only first argument is a string. |
6569 __ bind(&string1); | 6606 __ bind(&string1); |
6570 __ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_JS); | 6607 __ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_JS); |
6571 | 6608 |
(...skipping 2712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9284 | 9321 |
9285 // Just jump to runtime to add the two strings. | 9322 // Just jump to runtime to add the two strings. |
9286 __ bind(&string_add_runtime); | 9323 __ bind(&string_add_runtime); |
9287 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 9324 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
9288 } | 9325 } |
9289 | 9326 |
9290 | 9327 |
9291 #undef __ | 9328 #undef __ |
9292 | 9329 |
9293 } } // namespace v8::internal | 9330 } } // namespace v8::internal |
OLD | NEW |