OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1303 __ xori(v0, a0, 1 << Map::kIsUndetectable); | 1303 __ xori(v0, a0, 1 << Map::kIsUndetectable); |
1304 } | 1304 } |
1305 | 1305 |
1306 | 1306 |
1307 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, | 1307 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, |
1308 Register object, | 1308 Register object, |
1309 Register result, | 1309 Register result, |
1310 Register scratch1, | 1310 Register scratch1, |
1311 Register scratch2, | 1311 Register scratch2, |
1312 Register scratch3, | 1312 Register scratch3, |
1313 bool object_is_smi, | |
1314 Label* not_found) { | 1313 Label* not_found) { |
1315 // Use of registers. Register result is used as a temporary. | 1314 // Use of registers. Register result is used as a temporary. |
1316 Register number_string_cache = result; | 1315 Register number_string_cache = result; |
1317 Register mask = scratch3; | 1316 Register mask = scratch3; |
1318 | 1317 |
1319 // Load the number string cache. | 1318 // Load the number string cache. |
1320 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); | 1319 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); |
1321 | 1320 |
1322 // Make the hash mask from the length of the number string cache. It | 1321 // Make the hash mask from the length of the number string cache. It |
1323 // contains two elements (number and string) for each cache entry. | 1322 // contains two elements (number and string) for each cache entry. |
1324 __ lw(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset)); | 1323 __ lw(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset)); |
1325 // Divide length by two (length is a smi). | 1324 // Divide length by two (length is a smi). |
1326 __ sra(mask, mask, kSmiTagSize + 1); | 1325 __ sra(mask, mask, kSmiTagSize + 1); |
1327 __ Addu(mask, mask, -1); // Make mask. | 1326 __ Addu(mask, mask, -1); // Make mask. |
1328 | 1327 |
1329 // Calculate the entry in the number string cache. The hash value in the | 1328 // Calculate the entry in the number string cache. The hash value in the |
1330 // number string cache for smis is just the smi value, and the hash for | 1329 // number string cache for smis is just the smi value, and the hash for |
1331 // doubles is the xor of the upper and lower words. See | 1330 // doubles is the xor of the upper and lower words. See |
1332 // Heap::GetNumberStringCache. | 1331 // Heap::GetNumberStringCache. |
1333 Isolate* isolate = masm->isolate(); | 1332 Isolate* isolate = masm->isolate(); |
1334 Label is_smi; | 1333 Label is_smi; |
1335 Label load_result_from_cache; | 1334 Label load_result_from_cache; |
1336 if (!object_is_smi) { | 1335 __ JumpIfSmi(object, &is_smi); |
1337 __ JumpIfSmi(object, &is_smi); | 1336 __ CheckMap(object, |
1338 __ CheckMap(object, | 1337 scratch1, |
1339 scratch1, | 1338 Heap::kHeapNumberMapRootIndex, |
1340 Heap::kHeapNumberMapRootIndex, | 1339 not_found, |
1341 not_found, | 1340 DONT_DO_SMI_CHECK); |
1342 DONT_DO_SMI_CHECK); | |
1343 | 1341 |
1344 STATIC_ASSERT(8 == kDoubleSize); | 1342 STATIC_ASSERT(8 == kDoubleSize); |
1345 __ Addu(scratch1, | 1343 __ Addu(scratch1, |
1346 object, | 1344 object, |
1347 Operand(HeapNumber::kValueOffset - kHeapObjectTag)); | 1345 Operand(HeapNumber::kValueOffset - kHeapObjectTag)); |
1348 __ lw(scratch2, MemOperand(scratch1, kPointerSize)); | 1346 __ lw(scratch2, MemOperand(scratch1, kPointerSize)); |
1349 __ lw(scratch1, MemOperand(scratch1, 0)); | 1347 __ lw(scratch1, MemOperand(scratch1, 0)); |
1350 __ Xor(scratch1, scratch1, Operand(scratch2)); | 1348 __ Xor(scratch1, scratch1, Operand(scratch2)); |
1351 __ And(scratch1, scratch1, Operand(mask)); | 1349 __ And(scratch1, scratch1, Operand(mask)); |
1352 | 1350 |
1353 // Calculate address of entry in string cache: each entry consists | 1351 // Calculate address of entry in string cache: each entry consists |
1354 // of two pointer sized fields. | 1352 // of two pointer sized fields. |
1355 __ sll(scratch1, scratch1, kPointerSizeLog2 + 1); | 1353 __ sll(scratch1, scratch1, kPointerSizeLog2 + 1); |
1356 __ Addu(scratch1, number_string_cache, scratch1); | 1354 __ Addu(scratch1, number_string_cache, scratch1); |
1357 | 1355 |
1358 Register probe = mask; | 1356 Register probe = mask; |
1359 __ lw(probe, | 1357 __ lw(probe, |
1360 FieldMemOperand(scratch1, FixedArray::kHeaderSize)); | 1358 FieldMemOperand(scratch1, FixedArray::kHeaderSize)); |
1361 __ JumpIfSmi(probe, not_found); | 1359 __ JumpIfSmi(probe, not_found); |
1362 __ ldc1(f12, FieldMemOperand(object, HeapNumber::kValueOffset)); | 1360 __ ldc1(f12, FieldMemOperand(object, HeapNumber::kValueOffset)); |
1363 __ ldc1(f14, FieldMemOperand(probe, HeapNumber::kValueOffset)); | 1361 __ ldc1(f14, FieldMemOperand(probe, HeapNumber::kValueOffset)); |
1364 __ BranchF(&load_result_from_cache, NULL, eq, f12, f14); | 1362 __ BranchF(&load_result_from_cache, NULL, eq, f12, f14); |
1365 __ Branch(not_found); | 1363 __ Branch(not_found); |
1366 } | |
1367 | 1364 |
1368 __ bind(&is_smi); | 1365 __ bind(&is_smi); |
1369 Register scratch = scratch1; | 1366 Register scratch = scratch1; |
1370 __ sra(scratch, object, 1); // Shift away the tag. | 1367 __ sra(scratch, object, 1); // Shift away the tag. |
1371 __ And(scratch, mask, Operand(scratch)); | 1368 __ And(scratch, mask, Operand(scratch)); |
1372 | 1369 |
1373 // Calculate address of entry in string cache: each entry consists | 1370 // Calculate address of entry in string cache: each entry consists |
1374 // of two pointer sized fields. | 1371 // of two pointer sized fields. |
1375 __ sll(scratch, scratch, kPointerSizeLog2 + 1); | 1372 __ sll(scratch, scratch, kPointerSizeLog2 + 1); |
1376 __ Addu(scratch, number_string_cache, scratch); | 1373 __ Addu(scratch, number_string_cache, scratch); |
1377 | 1374 |
1378 // Check if the entry is the smi we are looking for. | 1375 // Check if the entry is the smi we are looking for. |
1379 Register probe = mask; | |
1380 __ lw(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | 1376 __ lw(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
1381 __ Branch(not_found, ne, object, Operand(probe)); | 1377 __ Branch(not_found, ne, object, Operand(probe)); |
1382 | 1378 |
1383 // Get the result from the cache. | 1379 // Get the result from the cache. |
1384 __ bind(&load_result_from_cache); | 1380 __ bind(&load_result_from_cache); |
1385 __ lw(result, | 1381 __ lw(result, |
1386 FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); | 1382 FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); |
1387 | 1383 |
1388 __ IncrementCounter(isolate->counters()->number_to_string_native(), | 1384 __ IncrementCounter(isolate->counters()->number_to_string_native(), |
1389 1, | 1385 1, |
1390 scratch1, | 1386 scratch1, |
1391 scratch2); | 1387 scratch2); |
1392 } | 1388 } |
1393 | 1389 |
1394 | 1390 |
1395 void NumberToStringStub::Generate(MacroAssembler* masm) { | 1391 void NumberToStringStub::Generate(MacroAssembler* masm) { |
1396 Label runtime; | 1392 Label runtime; |
1397 | 1393 |
1398 __ lw(a1, MemOperand(sp, 0)); | 1394 __ lw(a1, MemOperand(sp, 0)); |
1399 | 1395 |
1400 // Generate code to lookup number in the number string cache. | 1396 // Generate code to lookup number in the number string cache. |
1401 GenerateLookupNumberStringCache(masm, a1, v0, a2, a3, t0, false, &runtime); | 1397 GenerateLookupNumberStringCache(masm, a1, v0, a2, a3, t0, &runtime); |
1402 __ DropAndRet(1); | 1398 __ DropAndRet(1); |
1403 | 1399 |
1404 __ bind(&runtime); | 1400 __ bind(&runtime); |
1405 // Handle number to string in the runtime system if not found in the cache. | 1401 // Handle number to string in the runtime system if not found in the cache. |
1406 __ TailCallRuntime(Runtime::kNumberToString, 1, 1); | 1402 __ TailCallRuntime(Runtime::kNumberToString, 1, 1); |
1407 } | 1403 } |
1408 | 1404 |
1409 | 1405 |
1410 static void ICCompareStub_CheckInputType(MacroAssembler* masm, | 1406 static void ICCompareStub_CheckInputType(MacroAssembler* masm, |
1411 Register input, | 1407 Register input, |
(...skipping 4813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6225 // Check the number to string cache. | 6221 // Check the number to string cache. |
6226 Label not_cached; | 6222 Label not_cached; |
6227 __ bind(¬_string); | 6223 __ bind(¬_string); |
6228 // Puts the cached result into scratch1. | 6224 // Puts the cached result into scratch1. |
6229 NumberToStringStub::GenerateLookupNumberStringCache(masm, | 6225 NumberToStringStub::GenerateLookupNumberStringCache(masm, |
6230 arg, | 6226 arg, |
6231 scratch1, | 6227 scratch1, |
6232 scratch2, | 6228 scratch2, |
6233 scratch3, | 6229 scratch3, |
6234 scratch4, | 6230 scratch4, |
6235 false, | |
6236 ¬_cached); | 6231 ¬_cached); |
6237 __ mov(arg, scratch1); | 6232 __ mov(arg, scratch1); |
6238 __ sw(arg, MemOperand(sp, stack_offset)); | 6233 __ sw(arg, MemOperand(sp, stack_offset)); |
6239 __ jmp(&done); | 6234 __ jmp(&done); |
6240 | 6235 |
6241 // Check if the argument is a safe string wrapper. | 6236 // Check if the argument is a safe string wrapper. |
6242 __ bind(¬_cached); | 6237 __ bind(¬_cached); |
6243 __ JumpIfSmi(arg, slow); | 6238 __ JumpIfSmi(arg, slow); |
6244 __ GetObjectType(arg, scratch1, scratch2); // map -> scratch1. | 6239 __ GetObjectType(arg, scratch1, scratch2); // map -> scratch1. |
6245 __ Branch(slow, ne, scratch2, Operand(JS_VALUE_TYPE)); | 6240 __ Branch(slow, ne, scratch2, Operand(JS_VALUE_TYPE)); |
(...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7625 __ bind(&fast_elements_case); | 7620 __ bind(&fast_elements_case); |
7626 GenerateCase(masm, FAST_ELEMENTS); | 7621 GenerateCase(masm, FAST_ELEMENTS); |
7627 } | 7622 } |
7628 | 7623 |
7629 | 7624 |
7630 #undef __ | 7625 #undef __ |
7631 | 7626 |
7632 } } // namespace v8::internal | 7627 } } // namespace v8::internal |
7633 | 7628 |
7634 #endif // V8_TARGET_ARCH_MIPS | 7629 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |