Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(407)

Side by Side Diff: src/arm/ic-arm.cc

Issue 11028027: Revert trunk to bleeding_edge at r12484 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/full-codegen-arm.cc ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 __ Push(r2, r1, r0); 1294 __ Push(r2, r1, r0);
1295 1295
1296 __ mov(r1, Operand(Smi::FromInt(NONE))); // PropertyAttributes 1296 __ mov(r1, Operand(Smi::FromInt(NONE))); // PropertyAttributes
1297 __ mov(r0, Operand(Smi::FromInt(strict_mode))); // Strict mode. 1297 __ mov(r0, Operand(Smi::FromInt(strict_mode))); // Strict mode.
1298 __ Push(r1, r0); 1298 __ Push(r1, r0);
1299 1299
1300 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); 1300 __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
1301 } 1301 }
1302 1302
1303 1303
1304 static void KeyedStoreGenerateGenericHelper(
1305 MacroAssembler* masm,
1306 Label* fast_object,
1307 Label* fast_double,
1308 Label* slow,
1309 KeyedStoreCheckMap check_map,
1310 KeyedStoreIncrementLength increment_length,
1311 Register value,
1312 Register key,
1313 Register receiver,
1314 Register receiver_map,
1315 Register elements_map,
1316 Register elements) {
1317 Label transition_smi_elements;
1318 Label finish_object_store, non_double_value, transition_double_elements;
1319 Label fast_double_without_map_check;
1320
1321 // Fast case: Do the store, could be either Object or double.
1322 __ bind(fast_object);
1323 Register scratch_value = r4;
1324 Register address = r5;
1325 if (check_map == kCheckMap) {
1326 __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
1327 __ cmp(elements_map,
1328 Operand(masm->isolate()->factory()->fixed_array_map()));
1329 __ b(ne, fast_double);
1330 }
1331 // Smi stores don't require further checks.
1332 Label non_smi_value;
1333 __ JumpIfNotSmi(value, &non_smi_value);
1334
1335 if (increment_length == kIncrementLength) {
1336 // Add 1 to receiver->length.
1337 __ add(scratch_value, key, Operand(Smi::FromInt(1)));
1338 __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
1339 }
1340 // It's irrelevant whether array is smi-only or not when writing a smi.
1341 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1342 __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
1343 __ str(value, MemOperand(address));
1344 __ Ret();
1345
1346 __ bind(&non_smi_value);
1347 // Escape to elements kind transition case.
1348 __ CheckFastObjectElements(receiver_map, scratch_value,
1349 &transition_smi_elements);
1350
1351 // Fast elements array, store the value to the elements backing store.
1352 __ bind(&finish_object_store);
1353 if (increment_length == kIncrementLength) {
1354 // Add 1 to receiver->length.
1355 __ add(scratch_value, key, Operand(Smi::FromInt(1)));
1356 __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
1357 }
1358 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1359 __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
1360 __ str(value, MemOperand(address));
1361 // Update write barrier for the elements array address.
1362 __ mov(scratch_value, value); // Preserve the value which is returned.
1363 __ RecordWrite(elements,
1364 address,
1365 scratch_value,
1366 kLRHasNotBeenSaved,
1367 kDontSaveFPRegs,
1368 EMIT_REMEMBERED_SET,
1369 OMIT_SMI_CHECK);
1370 __ Ret();
1371
1372 __ bind(fast_double);
1373 if (check_map == kCheckMap) {
1374 // Check for fast double array case. If this fails, call through to the
1375 // runtime.
1376 __ CompareRoot(elements_map, Heap::kFixedDoubleArrayMapRootIndex);
1377 __ b(ne, slow);
1378 }
1379 __ bind(&fast_double_without_map_check);
1380 __ StoreNumberToDoubleElements(value,
1381 key,
1382 receiver,
1383 elements, // Overwritten.
1384 r3, // Scratch regs...
1385 r4,
1386 r5,
1387 r6,
1388 &transition_double_elements);
1389 if (increment_length == kIncrementLength) {
1390 // Add 1 to receiver->length.
1391 __ add(scratch_value, key, Operand(Smi::FromInt(1)));
1392 __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
1393 }
1394 __ Ret();
1395
1396 __ bind(&transition_smi_elements);
1397 // Transition the array appropriately depending on the value type.
1398 __ ldr(r4, FieldMemOperand(value, HeapObject::kMapOffset));
1399 __ CompareRoot(r4, Heap::kHeapNumberMapRootIndex);
1400 __ b(ne, &non_double_value);
1401
1402 // Value is a double. Transition FAST_SMI_ELEMENTS ->
1403 // FAST_DOUBLE_ELEMENTS and complete the store.
1404 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
1405 FAST_DOUBLE_ELEMENTS,
1406 receiver_map,
1407 r4,
1408 slow);
1409 ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
1410 ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow);
1411 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1412 __ jmp(&fast_double_without_map_check);
1413
1414 __ bind(&non_double_value);
1415 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
1416 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
1417 FAST_ELEMENTS,
1418 receiver_map,
1419 r4,
1420 slow);
1421 ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
1422 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
1423 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1424 __ jmp(&finish_object_store);
1425
1426 __ bind(&transition_double_elements);
1427 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
1428 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
1429 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
1430 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
1431 FAST_ELEMENTS,
1432 receiver_map,
1433 r4,
1434 slow);
1435 ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
1436 ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow);
1437 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1438 __ jmp(&finish_object_store);
1439 }
1440
1441
1442 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, 1304 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
1443 StrictModeFlag strict_mode) { 1305 StrictModeFlag strict_mode) {
1444 // ---------- S t a t e -------------- 1306 // ---------- S t a t e --------------
1445 // -- r0 : value 1307 // -- r0 : value
1446 // -- r1 : key 1308 // -- r1 : key
1447 // -- r2 : receiver 1309 // -- r2 : receiver
1448 // -- lr : return address 1310 // -- lr : return address
1449 // ----------------------------------- 1311 // -----------------------------------
1450 Label slow, fast_object, fast_object_grow; 1312 Label slow, array, extra, check_if_double_array;
1451 Label fast_double, fast_double_grow; 1313 Label fast_object_with_map_check, fast_object_without_map_check;
1452 Label array, extra, check_if_double_array; 1314 Label fast_double_with_map_check, fast_double_without_map_check;
1315 Label transition_smi_elements, finish_object_store, non_double_value;
1316 Label transition_double_elements;
1453 1317
1454 // Register usage. 1318 // Register usage.
1455 Register value = r0; 1319 Register value = r0;
1456 Register key = r1; 1320 Register key = r1;
1457 Register receiver = r2; 1321 Register receiver = r2;
1458 Register receiver_map = r3; 1322 Register receiver_map = r3;
1459 Register elements_map = r6; 1323 Register elements_map = r6;
1460 Register elements = r7; // Elements array of the receiver. 1324 Register elements = r7; // Elements array of the receiver.
1461 // r4 and r5 are used as general scratch registers. 1325 // r4 and r5 are used as general scratch registers.
1462 1326
(...skipping 14 matching lines...) Expand all
1477 __ b(eq, &array); 1341 __ b(eq, &array);
1478 // Check that the object is some kind of JSObject. 1342 // Check that the object is some kind of JSObject.
1479 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE)); 1343 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
1480 __ b(lt, &slow); 1344 __ b(lt, &slow);
1481 1345
1482 // Object case: Check key against length in the elements array. 1346 // Object case: Check key against length in the elements array.
1483 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 1347 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1484 // Check array bounds. Both the key and the length of FixedArray are smis. 1348 // Check array bounds. Both the key and the length of FixedArray are smis.
1485 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1349 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
1486 __ cmp(key, Operand(ip)); 1350 __ cmp(key, Operand(ip));
1487 __ b(lo, &fast_object); 1351 __ b(lo, &fast_object_with_map_check);
1488 1352
1489 // Slow case, handle jump to runtime. 1353 // Slow case, handle jump to runtime.
1490 __ bind(&slow); 1354 __ bind(&slow);
1491 // Entry registers are intact. 1355 // Entry registers are intact.
1492 // r0: value. 1356 // r0: value.
1493 // r1: key. 1357 // r1: key.
1494 // r2: receiver. 1358 // r2: receiver.
1495 GenerateRuntimeSetProperty(masm, strict_mode); 1359 GenerateRuntimeSetProperty(masm, strict_mode);
1496 1360
1497 // Extra capacity case: Check if there is extra capacity to 1361 // Extra capacity case: Check if there is extra capacity to
1498 // perform the store and update the length. Used for adding one 1362 // perform the store and update the length. Used for adding one
1499 // element to the array by writing to array[array.length]. 1363 // element to the array by writing to array[array.length].
1500 __ bind(&extra); 1364 __ bind(&extra);
1501 // Condition code from comparing key and array length is still available. 1365 // Condition code from comparing key and array length is still available.
1502 __ b(ne, &slow); // Only support writing to writing to array[array.length]. 1366 __ b(ne, &slow); // Only support writing to writing to array[array.length].
1503 // Check for room in the elements backing store. 1367 // Check for room in the elements backing store.
1504 // Both the key and the length of FixedArray are smis. 1368 // Both the key and the length of FixedArray are smis.
1505 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1369 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
1506 __ cmp(key, Operand(ip)); 1370 __ cmp(key, Operand(ip));
1507 __ b(hs, &slow); 1371 __ b(hs, &slow);
1508 __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset)); 1372 __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
1509 __ cmp(elements_map, 1373 __ cmp(elements_map,
1510 Operand(masm->isolate()->factory()->fixed_array_map())); 1374 Operand(masm->isolate()->factory()->fixed_array_map()));
1511 __ b(ne, &check_if_double_array); 1375 __ b(ne, &check_if_double_array);
1512 __ jmp(&fast_object_grow); 1376 // Calculate key + 1 as smi.
1377 STATIC_ASSERT(kSmiTag == 0);
1378 __ add(r4, key, Operand(Smi::FromInt(1)));
1379 __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset));
1380 __ b(&fast_object_without_map_check);
1513 1381
1514 __ bind(&check_if_double_array); 1382 __ bind(&check_if_double_array);
1515 __ cmp(elements_map, 1383 __ cmp(elements_map,
1516 Operand(masm->isolate()->factory()->fixed_double_array_map())); 1384 Operand(masm->isolate()->factory()->fixed_double_array_map()));
1517 __ b(ne, &slow); 1385 __ b(ne, &slow);
1518 __ jmp(&fast_double_grow); 1386 // Add 1 to key, and go to common element store code for doubles.
1387 STATIC_ASSERT(kSmiTag == 0);
1388 __ add(r4, key, Operand(Smi::FromInt(1)));
1389 __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset));
1390 __ jmp(&fast_double_without_map_check);
1519 1391
1520 // Array case: Get the length and the elements array from the JS 1392 // Array case: Get the length and the elements array from the JS
1521 // array. Check that the array is in fast mode (and writable); if it 1393 // array. Check that the array is in fast mode (and writable); if it
1522 // is the length is always a smi. 1394 // is the length is always a smi.
1523 __ bind(&array); 1395 __ bind(&array);
1524 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 1396 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1525 1397
1526 // Check the key against the length in the array. 1398 // Check the key against the length in the array.
1527 __ ldr(ip, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1399 __ ldr(ip, FieldMemOperand(receiver, JSArray::kLengthOffset));
1528 __ cmp(key, Operand(ip)); 1400 __ cmp(key, Operand(ip));
1529 __ b(hs, &extra); 1401 __ b(hs, &extra);
1402 // Fall through to fast case.
1530 1403
1531 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, 1404 __ bind(&fast_object_with_map_check);
1532 &slow, kCheckMap, kDontIncrementLength, 1405 Register scratch_value = r4;
1533 value, key, receiver, receiver_map, 1406 Register address = r5;
1534 elements_map, elements); 1407 __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
1535 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, 1408 __ cmp(elements_map,
1536 &slow, kDontCheckMap, kIncrementLength, 1409 Operand(masm->isolate()->factory()->fixed_array_map()));
1537 value, key, receiver, receiver_map, 1410 __ b(ne, &fast_double_with_map_check);
1538 elements_map, elements); 1411 __ bind(&fast_object_without_map_check);
1412 // Smi stores don't require further checks.
1413 Label non_smi_value;
1414 __ JumpIfNotSmi(value, &non_smi_value);
1415 // It's irrelevant whether array is smi-only or not when writing a smi.
1416 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1417 __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
1418 __ str(value, MemOperand(address));
1419 __ Ret();
1420
1421 __ bind(&non_smi_value);
1422 // Escape to elements kind transition case.
1423 __ CheckFastObjectElements(receiver_map, scratch_value,
1424 &transition_smi_elements);
1425 // Fast elements array, store the value to the elements backing store.
1426 __ bind(&finish_object_store);
1427 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1428 __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
1429 __ str(value, MemOperand(address));
1430 // Update write barrier for the elements array address.
1431 __ mov(scratch_value, value); // Preserve the value which is returned.
1432 __ RecordWrite(elements,
1433 address,
1434 scratch_value,
1435 kLRHasNotBeenSaved,
1436 kDontSaveFPRegs,
1437 EMIT_REMEMBERED_SET,
1438 OMIT_SMI_CHECK);
1439 __ Ret();
1440
1441 __ bind(&fast_double_with_map_check);
1442 // Check for fast double array case. If this fails, call through to the
1443 // runtime.
1444 __ cmp(elements_map,
1445 Operand(masm->isolate()->factory()->fixed_double_array_map()));
1446 __ b(ne, &slow);
1447 __ bind(&fast_double_without_map_check);
1448 __ StoreNumberToDoubleElements(value,
1449 key,
1450 receiver,
1451 elements,
1452 r3,
1453 r4,
1454 r5,
1455 r6,
1456 &transition_double_elements);
1457 __ Ret();
1458
1459 __ bind(&transition_smi_elements);
1460 // Transition the array appropriately depending on the value type.
1461 __ ldr(r4, FieldMemOperand(value, HeapObject::kMapOffset));
1462 __ CompareRoot(r4, Heap::kHeapNumberMapRootIndex);
1463 __ b(ne, &non_double_value);
1464
1465 // Value is a double. Transition FAST_SMI_ELEMENTS ->
1466 // FAST_DOUBLE_ELEMENTS and complete the store.
1467 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
1468 FAST_DOUBLE_ELEMENTS,
1469 receiver_map,
1470 r4,
1471 &slow);
1472 ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
1473 ElementsTransitionGenerator::GenerateSmiToDouble(masm, &slow);
1474 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1475 __ jmp(&fast_double_without_map_check);
1476
1477 __ bind(&non_double_value);
1478 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
1479 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
1480 FAST_ELEMENTS,
1481 receiver_map,
1482 r4,
1483 &slow);
1484 ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
1485 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
1486 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1487 __ jmp(&finish_object_store);
1488
1489 __ bind(&transition_double_elements);
1490 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
1491 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
1492 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
1493 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
1494 FAST_ELEMENTS,
1495 receiver_map,
1496 r4,
1497 &slow);
1498 ASSERT(receiver_map.is(r3)); // Transition code expects map in r3
1499 ElementsTransitionGenerator::GenerateDoubleToObject(masm, &slow);
1500 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1501 __ jmp(&finish_object_store);
1539 } 1502 }
1540 1503
1541 1504
1542 void StoreIC::GenerateMegamorphic(MacroAssembler* masm, 1505 void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
1543 StrictModeFlag strict_mode) { 1506 StrictModeFlag strict_mode) {
1544 // ----------- S t a t e ------------- 1507 // ----------- S t a t e -------------
1545 // -- r0 : value 1508 // -- r0 : value
1546 // -- r1 : receiver 1509 // -- r1 : receiver
1547 // -- r2 : name 1510 // -- r2 : name
1548 // -- lr : return address 1511 // -- lr : return address
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1792 } else { 1755 } else {
1793 ASSERT(Assembler::GetCondition(branch_instr) == ne); 1756 ASSERT(Assembler::GetCondition(branch_instr) == ne);
1794 patcher.EmitCondition(eq); 1757 patcher.EmitCondition(eq);
1795 } 1758 }
1796 } 1759 }
1797 1760
1798 1761
1799 } } // namespace v8::internal 1762 } } // namespace v8::internal
1800 1763
1801 #endif // V8_TARGET_ARCH_ARM 1764 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/full-codegen-arm.cc ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698