| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 1446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1457 // Get the elements array of the object. | 1457 // Get the elements array of the object. |
| 1458 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); | 1458 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); |
| 1459 | 1459 |
| 1460 // Check that the elements are in fast mode and writable. | 1460 // Check that the elements are in fast mode and writable. |
| 1461 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), | 1461 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), |
| 1462 Immediate(Factory::fixed_array_map())); | 1462 Immediate(Factory::fixed_array_map())); |
| 1463 __ j(not_equal, &call_builtin); | 1463 __ j(not_equal, &call_builtin); |
| 1464 | 1464 |
| 1465 if (argc == 1) { // Otherwise fall through to call builtin. | 1465 if (argc == 1) { // Otherwise fall through to call builtin. |
| 1466 Label exit, attempt_to_grow_elements; | 1466 Label exit, attempt_to_grow_elements; |
| 1467 Label with_write_barrier; | 1467 NearLabel with_write_barrier; |
| 1468 | 1468 |
| 1469 // Get the array's length into eax and calculate new length. | 1469 // Get the array's length into eax and calculate new length. |
| 1470 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); | 1470 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); |
| 1471 STATIC_ASSERT(kSmiTagSize == 1); | 1471 STATIC_ASSERT(kSmiTagSize == 1); |
| 1472 STATIC_ASSERT(kSmiTag == 0); | 1472 STATIC_ASSERT(kSmiTag == 0); |
| 1473 __ add(Operand(eax), Immediate(Smi::FromInt(argc))); | 1473 __ add(Operand(eax), Immediate(Smi::FromInt(argc))); |
| 1474 | 1474 |
| 1475 // Get the element's length into ecx. | 1475 // Get the element's length into ecx. |
| 1476 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); | 1476 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); |
| 1477 | 1477 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1491 | 1491 |
| 1492 // Check if value is a smi. | 1492 // Check if value is a smi. |
| 1493 __ test(ecx, Immediate(kSmiTagMask)); | 1493 __ test(ecx, Immediate(kSmiTagMask)); |
| 1494 __ j(not_zero, &with_write_barrier); | 1494 __ j(not_zero, &with_write_barrier); |
| 1495 | 1495 |
| 1496 __ bind(&exit); | 1496 __ bind(&exit); |
| 1497 __ ret((argc + 1) * kPointerSize); | 1497 __ ret((argc + 1) * kPointerSize); |
| 1498 | 1498 |
| 1499 __ bind(&with_write_barrier); | 1499 __ bind(&with_write_barrier); |
| 1500 | 1500 |
| 1501 __ IncrementalMarkingRecordWrite(ebx, | 1501 __ RecordWrite( |
| 1502 ecx, | 1502 ebx, edx, ecx, EMIT_REMEMBERED_SET, kDontSaveFPRegs, OMIT_SMI_CHECK); |
| 1503 edx, | |
| 1504 OMIT_SMI_CHECK, | |
| 1505 PRESERVE_OBJECT, | |
| 1506 DESTROY_VALUE, | |
| 1507 PRESERVE_SCRATCH); | |
| 1508 | 1503 |
| 1509 __ InNewSpace(ebx, ecx, equal, &exit); | |
| 1510 | |
| 1511 __ RecordWriteHelper(ebx, edx, ecx, kDontSaveFPRegs); | |
| 1512 __ ret((argc + 1) * kPointerSize); | 1504 __ ret((argc + 1) * kPointerSize); |
| 1513 | 1505 |
| 1514 __ bind(&attempt_to_grow_elements); | 1506 __ bind(&attempt_to_grow_elements); |
| 1515 if (!FLAG_inline_new) { | 1507 if (!FLAG_inline_new) { |
| 1516 __ jmp(&call_builtin); | 1508 __ jmp(&call_builtin); |
| 1517 } | 1509 } |
| 1518 | 1510 |
| 1511 // We could be lucky and the elements array could be at the top of |
| 1512 // new-space. In this case we can just grow it in place by moving the |
| 1513 // allocation pointer up. |
| 1514 |
| 1519 ExternalReference new_space_allocation_top = | 1515 ExternalReference new_space_allocation_top = |
| 1520 ExternalReference::new_space_allocation_top_address(); | 1516 ExternalReference::new_space_allocation_top_address(); |
| 1521 ExternalReference new_space_allocation_limit = | 1517 ExternalReference new_space_allocation_limit = |
| 1522 ExternalReference::new_space_allocation_limit_address(); | 1518 ExternalReference::new_space_allocation_limit_address(); |
| 1523 | 1519 |
| 1524 const int kAllocationDelta = 4; | 1520 const int kAllocationDelta = 4; |
| 1525 // Load top. | 1521 // Load top. |
| 1526 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); | 1522 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); |
| 1527 | 1523 |
| 1528 // Check if it's the end of elements. | 1524 // Check if it's the end of elements. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1540 __ mov(ecx, Operand(esp, argc * kPointerSize)); | 1536 __ mov(ecx, Operand(esp, argc * kPointerSize)); |
| 1541 | 1537 |
| 1542 // Push the argument... | 1538 // Push the argument... |
| 1543 __ mov(Operand(edx, 0), ecx); | 1539 __ mov(Operand(edx, 0), ecx); |
| 1544 // ... and fill the rest with holes. | 1540 // ... and fill the rest with holes. |
| 1545 for (int i = 1; i < kAllocationDelta; i++) { | 1541 for (int i = 1; i < kAllocationDelta; i++) { |
| 1546 __ mov(Operand(edx, i * kPointerSize), | 1542 __ mov(Operand(edx, i * kPointerSize), |
| 1547 Immediate(Factory::the_hole_value())); | 1543 Immediate(Factory::the_hole_value())); |
| 1548 } | 1544 } |
| 1549 | 1545 |
| 1550 __ IncrementalMarkingRecordWrite(ebx, | 1546 // We know the elements array is in new space so we don't need the |
| 1551 ecx, | 1547 // remembered set, but we just pushed a value onto it so we may have to |
| 1552 edx, | 1548 // tell the incremental marker to rescan the object that we just grew. We |
| 1553 INLINE_SMI_CHECK, | 1549 // don't need to worry about the holes because they are in old space and |
| 1554 PRESERVE_OBJECT, | 1550 // already marked black. |
| 1555 DESTROY_VALUE, | 1551 __ mov(edi, ebx); |
| 1556 DESTROY_SCRATCH); | 1552 __ RecordWrite(edi, edx, ecx, OMIT_REMEMBERED_SET, kDontSaveFPRegs); |
| 1557 | 1553 |
| 1558 // Restore receiver to edx as finish sequence assumes it's here. | 1554 // Restore receiver to edx as finish sequence assumes it's here. |
| 1559 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1555 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 1560 | 1556 |
| 1561 // Increment element's and array's sizes. | 1557 // Increment element's and array's sizes. |
| 1562 __ add(FieldOperand(ebx, FixedArray::kLengthOffset), | 1558 __ add(FieldOperand(ebx, FixedArray::kLengthOffset), |
| 1563 Immediate(Smi::FromInt(kAllocationDelta))); | 1559 Immediate(Smi::FromInt(kAllocationDelta))); |
| 1564 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); | 1560 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); |
| 1565 | 1561 |
| 1566 // Elements are in new space, so write barrier is not required. | 1562 // Elements are in new space, so write barrier is not required. |
| (...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2614 __ cmp(cell_operand, Factory::the_hole_value()); | 2610 __ cmp(cell_operand, Factory::the_hole_value()); |
| 2615 __ j(equal, &miss); | 2611 __ j(equal, &miss); |
| 2616 | 2612 |
| 2617 // Store the value in the cell. | 2613 // Store the value in the cell. |
| 2618 __ mov(cell_operand, eax); | 2614 __ mov(cell_operand, eax); |
| 2619 Label done; | 2615 Label done; |
| 2620 __ test(eax, Immediate(kSmiTagMask)); | 2616 __ test(eax, Immediate(kSmiTagMask)); |
| 2621 __ j(zero, &done); | 2617 __ j(zero, &done); |
| 2622 | 2618 |
| 2623 __ mov(ecx, eax); | 2619 __ mov(ecx, eax); |
| 2624 __ IncrementalMarkingRecordWrite(ebx, | 2620 // Cells are always in the remembered set. |
| 2625 ecx, | 2621 __ RecordWrite(ebx, edx, ecx, OMIT_REMEMBERED_SET, kDontSaveFPRegs); |
| 2626 edx, | |
| 2627 INLINE_SMI_CHECK, | |
| 2628 DESTROY_OBJECT, | |
| 2629 DESTROY_VALUE, | |
| 2630 DESTROY_SCRATCH); | |
| 2631 | 2622 |
| 2632 // Return the value (register eax). | 2623 // Return the value (register eax). |
| 2633 __ bind(&done); | 2624 __ bind(&done); |
| 2634 | 2625 |
| 2635 // Return the value (register eax). | 2626 // Return the value (register eax). |
| 2636 __ IncrementCounter(&Counters::named_store_global_inline, 1); | 2627 __ IncrementCounter(&Counters::named_store_global_inline, 1); |
| 2637 __ ret(0); | 2628 __ ret(0); |
| 2638 | 2629 |
| 2639 // Handle store cache miss. | 2630 // Handle store cache miss. |
| 2640 __ bind(&miss); | 2631 __ bind(&miss); |
| (...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3681 | 3672 |
| 3682 return GetCode(flags); | 3673 return GetCode(flags); |
| 3683 } | 3674 } |
| 3684 | 3675 |
| 3685 | 3676 |
| 3686 #undef __ | 3677 #undef __ |
| 3687 | 3678 |
| 3688 } } // namespace v8::internal | 3679 } } // namespace v8::internal |
| 3689 | 3680 |
| 3690 #endif // V8_TARGET_ARCH_IA32 | 3681 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |