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 1450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1461 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, a3, v0, t0, | 1461 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, a3, v0, t0, |
1462 name, &miss); | 1462 name, &miss); |
1463 | 1463 |
1464 if (argc == 0) { | 1464 if (argc == 0) { |
1465 // Nothing to do, just return the length. | 1465 // Nothing to do, just return the length. |
1466 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1466 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1467 __ Drop(argc + 1); | 1467 __ Drop(argc + 1); |
1468 __ Ret(); | 1468 __ Ret(); |
1469 } else { | 1469 } else { |
1470 Label call_builtin; | 1470 Label call_builtin; |
1471 Register elements = a3; | |
1472 Register end_elements = t1; | |
1473 // Get the elements array of the object. | |
1474 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); | |
1475 | |
1476 // Check that the elements are in fast mode and writable. | |
1477 __ CheckMap(elements, | |
1478 v0, | |
1479 Heap::kFixedArrayMapRootIndex, | |
1480 &call_builtin, | |
1481 DONT_DO_SMI_CHECK); | |
1482 | |
1483 if (argc == 1) { // Otherwise fall through to call the builtin. | 1471 if (argc == 1) { // Otherwise fall through to call the builtin. |
1484 Label attempt_to_grow_elements; | 1472 Label attempt_to_grow_elements; |
1485 | 1473 |
| 1474 Register elements = t2; |
| 1475 Register end_elements = t1; |
| 1476 // Get the elements array of the object. |
| 1477 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); |
| 1478 |
| 1479 // Check that the elements are in fast mode and writable. |
| 1480 __ CheckMap(elements, |
| 1481 v0, |
| 1482 Heap::kFixedArrayMapRootIndex, |
| 1483 &call_builtin, |
| 1484 DONT_DO_SMI_CHECK); |
| 1485 |
1486 // Get the array's length into v0 and calculate new length. | 1486 // Get the array's length into v0 and calculate new length. |
1487 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1487 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1488 STATIC_ASSERT(kSmiTagSize == 1); | 1488 STATIC_ASSERT(kSmiTagSize == 1); |
1489 STATIC_ASSERT(kSmiTag == 0); | 1489 STATIC_ASSERT(kSmiTag == 0); |
1490 __ Addu(v0, v0, Operand(Smi::FromInt(argc))); | 1490 __ Addu(v0, v0, Operand(Smi::FromInt(argc))); |
1491 | 1491 |
1492 // Get the element's length. | 1492 // Get the elements' length. |
1493 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); | 1493 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
1494 | 1494 |
1495 // Check if we could survive without allocation. | 1495 // Check if we could survive without allocation. |
1496 __ Branch(&attempt_to_grow_elements, gt, v0, Operand(t0)); | 1496 __ Branch(&attempt_to_grow_elements, gt, v0, Operand(t0)); |
1497 | 1497 |
1498 // Check if value is a smi. | 1498 // Check if value is a smi. |
1499 Label with_write_barrier; | 1499 Label with_write_barrier; |
1500 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize)); | 1500 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize)); |
1501 __ JumpIfNotSmi(t0, &with_write_barrier); | 1501 __ JumpIfNotSmi(t0, &with_write_barrier); |
1502 | 1502 |
1503 // Save new length. | 1503 // Save new length. |
1504 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1504 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1505 | 1505 |
1506 // Push the element. | 1506 // Store the value. |
1507 // We may need a register containing the address end_elements below, | 1507 // We may need a register containing the address end_elements below, |
1508 // so write back the value in end_elements. | 1508 // so write back the value in end_elements. |
1509 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); | 1509 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); |
1510 __ Addu(end_elements, elements, end_elements); | 1510 __ Addu(end_elements, elements, end_elements); |
1511 const int kEndElementsOffset = | 1511 const int kEndElementsOffset = |
1512 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; | 1512 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; |
1513 __ Addu(end_elements, end_elements, kEndElementsOffset); | 1513 __ Addu(end_elements, end_elements, kEndElementsOffset); |
1514 __ sw(t0, MemOperand(end_elements)); | 1514 __ sw(t0, MemOperand(end_elements)); |
1515 | 1515 |
1516 // Check for a smi. | 1516 // Check for a smi. |
1517 __ Drop(argc + 1); | 1517 __ Drop(argc + 1); |
1518 __ Ret(); | 1518 __ Ret(); |
1519 | 1519 |
1520 __ bind(&with_write_barrier); | 1520 __ bind(&with_write_barrier); |
1521 | 1521 |
1522 __ lw(t2, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1522 __ lw(a3, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
1523 __ CheckFastObjectElements(t2, t2, &call_builtin); | 1523 |
| 1524 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) { |
| 1525 Label fast_object, not_fast_object; |
| 1526 __ CheckFastObjectElements(a3, t3, ¬_fast_object); |
| 1527 __ jmp(&fast_object); |
| 1528 // In case of fast smi-only, convert to fast object, otherwise bail out. |
| 1529 __ bind(¬_fast_object); |
| 1530 __ CheckFastSmiOnlyElements(a3, t3, &call_builtin); |
| 1531 // edx: receiver |
| 1532 // r3: map |
| 1533 __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS, |
| 1534 FAST_ELEMENTS, |
| 1535 a3, |
| 1536 t3, |
| 1537 &call_builtin); |
| 1538 __ mov(a2, receiver); |
| 1539 ElementsTransitionGenerator::GenerateSmiOnlyToObject(masm()); |
| 1540 __ bind(&fast_object); |
| 1541 } else { |
| 1542 __ CheckFastObjectElements(a3, a3, &call_builtin); |
| 1543 } |
1524 | 1544 |
1525 // Save new length. | 1545 // Save new length. |
1526 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1546 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1527 | 1547 |
1528 // Push the element. | 1548 // Store the value. |
1529 // We may need a register containing the address end_elements below, | 1549 // We may need a register containing the address end_elements below, |
1530 // so write back the value in end_elements. | 1550 // so write back the value in end_elements. |
1531 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); | 1551 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); |
1532 __ Addu(end_elements, elements, end_elements); | 1552 __ Addu(end_elements, elements, end_elements); |
1533 __ Addu(end_elements, end_elements, kEndElementsOffset); | 1553 __ Addu(end_elements, end_elements, kEndElementsOffset); |
1534 __ sw(t0, MemOperand(end_elements)); | 1554 __ sw(t0, MemOperand(end_elements)); |
1535 | 1555 |
1536 __ RecordWrite(elements, | 1556 __ RecordWrite(elements, |
1537 end_elements, | 1557 end_elements, |
1538 t0, | 1558 t0, |
(...skipping 27 matching lines...) Expand all Loading... |
1566 ExternalReference new_space_allocation_limit = | 1586 ExternalReference new_space_allocation_limit = |
1567 ExternalReference::new_space_allocation_limit_address( | 1587 ExternalReference::new_space_allocation_limit_address( |
1568 masm()->isolate()); | 1588 masm()->isolate()); |
1569 | 1589 |
1570 const int kAllocationDelta = 4; | 1590 const int kAllocationDelta = 4; |
1571 // Load top and check if it is the end of elements. | 1591 // Load top and check if it is the end of elements. |
1572 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); | 1592 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); |
1573 __ Addu(end_elements, elements, end_elements); | 1593 __ Addu(end_elements, elements, end_elements); |
1574 __ Addu(end_elements, end_elements, Operand(kEndElementsOffset)); | 1594 __ Addu(end_elements, end_elements, Operand(kEndElementsOffset)); |
1575 __ li(t3, Operand(new_space_allocation_top)); | 1595 __ li(t3, Operand(new_space_allocation_top)); |
1576 __ lw(t2, MemOperand(t3)); | 1596 __ lw(a3, MemOperand(t3)); |
1577 __ Branch(&call_builtin, ne, end_elements, Operand(t2)); | 1597 __ Branch(&call_builtin, ne, end_elements, Operand(a3)); |
1578 | 1598 |
1579 __ li(t5, Operand(new_space_allocation_limit)); | 1599 __ li(t5, Operand(new_space_allocation_limit)); |
1580 __ lw(t5, MemOperand(t5)); | 1600 __ lw(t5, MemOperand(t5)); |
1581 __ Addu(t2, t2, Operand(kAllocationDelta * kPointerSize)); | 1601 __ Addu(a3, a3, Operand(kAllocationDelta * kPointerSize)); |
1582 __ Branch(&call_builtin, hi, t2, Operand(t5)); | 1602 __ Branch(&call_builtin, hi, a3, Operand(t5)); |
1583 | 1603 |
1584 // We fit and could grow elements. | 1604 // We fit and could grow elements. |
1585 // Update new_space_allocation_top. | 1605 // Update new_space_allocation_top. |
1586 __ sw(t2, MemOperand(t3)); | 1606 __ sw(a3, MemOperand(t3)); |
1587 // Push the argument. | 1607 // Push the argument. |
1588 __ sw(a2, MemOperand(end_elements)); | 1608 __ sw(a2, MemOperand(end_elements)); |
1589 // Fill the rest with holes. | 1609 // Fill the rest with holes. |
1590 __ LoadRoot(t2, Heap::kTheHoleValueRootIndex); | 1610 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); |
1591 for (int i = 1; i < kAllocationDelta; i++) { | 1611 for (int i = 1; i < kAllocationDelta; i++) { |
1592 __ sw(t2, MemOperand(end_elements, i * kPointerSize)); | 1612 __ sw(a3, MemOperand(end_elements, i * kPointerSize)); |
1593 } | 1613 } |
1594 | 1614 |
1595 // Update elements' and array's sizes. | 1615 // Update elements' and array's sizes. |
1596 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1616 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1597 __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta))); | 1617 __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta))); |
1598 __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); | 1618 __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
1599 | 1619 |
1600 // Elements are in new space, so write barrier is not required. | 1620 // Elements are in new space, so write barrier is not required. |
1601 __ Drop(argc + 1); | 1621 __ Drop(argc + 1); |
1602 __ Ret(); | 1622 __ Ret(); |
(...skipping 2695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4298 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4318 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
4299 __ Jump(ic_miss, RelocInfo::CODE_TARGET); | 4319 __ Jump(ic_miss, RelocInfo::CODE_TARGET); |
4300 } | 4320 } |
4301 | 4321 |
4302 | 4322 |
4303 #undef __ | 4323 #undef __ |
4304 | 4324 |
4305 } } // namespace v8::internal | 4325 } } // namespace v8::internal |
4306 | 4326 |
4307 #endif // V8_TARGET_ARCH_MIPS | 4327 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |