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

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

Issue 10985017: Turn get-own-property-descriptor.js test into a regression (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
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 | « no previous file | src/builtins.cc » ('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,
1384 r3,
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
1304 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, 1442 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
1305 StrictModeFlag strict_mode) { 1443 StrictModeFlag strict_mode) {
1306 // ---------- S t a t e -------------- 1444 // ---------- S t a t e --------------
1307 // -- r0 : value 1445 // -- r0 : value
1308 // -- r1 : key 1446 // -- r1 : key
1309 // -- r2 : receiver 1447 // -- r2 : receiver
1310 // -- lr : return address 1448 // -- lr : return address
1311 // ----------------------------------- 1449 // -----------------------------------
1312 Label slow, array, extra, check_if_double_array; 1450 Label slow, fast_object, fast_object_grow;
1313 Label fast_object_with_map_check, fast_object_without_map_check; 1451 Label fast_double, fast_double_grow;
1314 Label fast_double_with_map_check, fast_double_without_map_check; 1452 Label array, extra, check_if_double_array;
1315 Label transition_smi_elements, finish_object_store, non_double_value;
1316 Label transition_double_elements;
1317 1453
1318 // Register usage. 1454 // Register usage.
1319 Register value = r0; 1455 Register value = r0;
1320 Register key = r1; 1456 Register key = r1;
1321 Register receiver = r2; 1457 Register receiver = r2;
1322 Register receiver_map = r3; 1458 Register receiver_map = r3;
1323 Register elements_map = r6; 1459 Register elements_map = r6;
1324 Register elements = r7; // Elements array of the receiver. 1460 Register elements = r7; // Elements array of the receiver.
1325 // r4 and r5 are used as general scratch registers. 1461 // r4 and r5 are used as general scratch registers.
1326 1462
(...skipping 14 matching lines...) Expand all
1341 __ b(eq, &array); 1477 __ b(eq, &array);
1342 // Check that the object is some kind of JSObject. 1478 // Check that the object is some kind of JSObject.
1343 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE)); 1479 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
1344 __ b(lt, &slow); 1480 __ b(lt, &slow);
1345 1481
1346 // Object case: Check key against length in the elements array. 1482 // Object case: Check key against length in the elements array.
1347 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 1483 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1348 // Check array bounds. Both the key and the length of FixedArray are smis. 1484 // Check array bounds. Both the key and the length of FixedArray are smis.
1349 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1485 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
1350 __ cmp(key, Operand(ip)); 1486 __ cmp(key, Operand(ip));
1351 __ b(lo, &fast_object_with_map_check); 1487 __ b(lo, &fast_object);
1352 1488
1353 // Slow case, handle jump to runtime. 1489 // Slow case, handle jump to runtime.
1354 __ bind(&slow); 1490 __ bind(&slow);
1355 // Entry registers are intact. 1491 // Entry registers are intact.
1356 // r0: value. 1492 // r0: value.
1357 // r1: key. 1493 // r1: key.
1358 // r2: receiver. 1494 // r2: receiver.
1359 GenerateRuntimeSetProperty(masm, strict_mode); 1495 GenerateRuntimeSetProperty(masm, strict_mode);
1360 1496
1361 // Extra capacity case: Check if there is extra capacity to 1497 // Extra capacity case: Check if there is extra capacity to
1362 // perform the store and update the length. Used for adding one 1498 // perform the store and update the length. Used for adding one
1363 // element to the array by writing to array[array.length]. 1499 // element to the array by writing to array[array.length].
1364 __ bind(&extra); 1500 __ bind(&extra);
1365 // Condition code from comparing key and array length is still available. 1501 // Condition code from comparing key and array length is still available.
1366 __ b(ne, &slow); // Only support writing to writing to array[array.length]. 1502 __ b(ne, &slow); // Only support writing to writing to array[array.length].
1367 // Check for room in the elements backing store. 1503 // Check for room in the elements backing store.
1368 // Both the key and the length of FixedArray are smis. 1504 // Both the key and the length of FixedArray are smis.
1369 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1505 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
1370 __ cmp(key, Operand(ip)); 1506 __ cmp(key, Operand(ip));
1371 __ b(hs, &slow); 1507 __ b(hs, &slow);
1372 __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset)); 1508 __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
1373 __ cmp(elements_map, 1509 __ cmp(elements_map,
1374 Operand(masm->isolate()->factory()->fixed_array_map())); 1510 Operand(masm->isolate()->factory()->fixed_array_map()));
1375 __ b(ne, &check_if_double_array); 1511 __ b(ne, &check_if_double_array);
1376 // Calculate key + 1 as smi. 1512 __ jmp(&fast_object_grow);
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);
1381 1513
1382 __ bind(&check_if_double_array); 1514 __ bind(&check_if_double_array);
1383 __ cmp(elements_map, 1515 __ cmp(elements_map,
1384 Operand(masm->isolate()->factory()->fixed_double_array_map())); 1516 Operand(masm->isolate()->factory()->fixed_double_array_map()));
1385 __ b(ne, &slow); 1517 __ b(ne, &slow);
1386 // Add 1 to key, and go to common element store code for doubles. 1518 __ jmp(&fast_double_grow);
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);
1391 1519
1392 // Array case: Get the length and the elements array from the JS 1520 // Array case: Get the length and the elements array from the JS
1393 // array. Check that the array is in fast mode (and writable); if it 1521 // array. Check that the array is in fast mode (and writable); if it
1394 // is the length is always a smi. 1522 // is the length is always a smi.
1395 __ bind(&array); 1523 __ bind(&array);
1396 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 1524 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1397 1525
1398 // Check the key against the length in the array. 1526 // Check the key against the length in the array.
1399 __ ldr(ip, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1527 __ ldr(ip, FieldMemOperand(receiver, JSArray::kLengthOffset));
1400 __ cmp(key, Operand(ip)); 1528 __ cmp(key, Operand(ip));
1401 __ b(hs, &extra); 1529 __ b(hs, &extra);
1402 // Fall through to fast case.
1403 1530
1404 __ bind(&fast_object_with_map_check); 1531 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
1405 Register scratch_value = r4; 1532 &slow, kCheckMap, kDontIncrementLength,
1406 Register address = r5; 1533 value, key, receiver, receiver_map,
1407 __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset)); 1534 elements_map, elements);
1408 __ cmp(elements_map, 1535 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
1409 Operand(masm->isolate()->factory()->fixed_array_map())); 1536 &slow, kDontCheckMap, kIncrementLength,
1410 __ b(ne, &fast_double_with_map_check); 1537 value, key, receiver, receiver_map,
1411 __ bind(&fast_object_without_map_check); 1538 elements_map, elements);
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);
1502 } 1539 }
1503 1540
1504 1541
1505 void StoreIC::GenerateMegamorphic(MacroAssembler* masm, 1542 void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
1506 StrictModeFlag strict_mode) { 1543 StrictModeFlag strict_mode) {
1507 // ----------- S t a t e ------------- 1544 // ----------- S t a t e -------------
1508 // -- r0 : value 1545 // -- r0 : value
1509 // -- r1 : receiver 1546 // -- r1 : receiver
1510 // -- r2 : name 1547 // -- r2 : name
1511 // -- lr : return address 1548 // -- lr : return address
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1755 } else { 1792 } else {
1756 ASSERT(Assembler::GetCondition(branch_instr) == ne); 1793 ASSERT(Assembler::GetCondition(branch_instr) == ne);
1757 patcher.EmitCondition(eq); 1794 patcher.EmitCondition(eq);
1758 } 1795 }
1759 } 1796 }
1760 1797
1761 1798
1762 } } // namespace v8::internal 1799 } } // namespace v8::internal
1763 1800
1764 #endif // V8_TARGET_ARCH_ARM 1801 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/builtins.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698