| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 | 414 |
| 415 // Generate code to check that a global property cell is empty. Create | 415 // Generate code to check that a global property cell is empty. Create |
| 416 // the property cell at compilation time if no cell exists for the | 416 // the property cell at compilation time if no cell exists for the |
| 417 // property. | 417 // property. |
| 418 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 418 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 419 Handle<GlobalObject> global, | 419 Handle<GlobalObject> global, |
| 420 Handle<Name> name, | 420 Handle<Name> name, |
| 421 Register scratch, | 421 Register scratch, |
| 422 Register the_hole, | 422 Register the_hole, |
| 423 Label* miss) { | 423 Label* miss) { |
| 424 Handle<JSGlobalPropertyCell> cell = | 424 Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name); |
| 425 GlobalObject::EnsurePropertyCell(global, name); | |
| 426 ASSERT(cell->value()->IsTheHole()); | 425 ASSERT(cell->value()->IsTheHole()); |
| 427 __ Mov(scratch, Operand(cell)); | 426 __ Mov(scratch, Operand(cell)); |
| 428 __ Ldr(scratch, | 427 __ Ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); |
| 429 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | |
| 430 __ Cmp(scratch, the_hole); | 428 __ Cmp(scratch, the_hole); |
| 431 __ B(ne, miss); | 429 __ B(ne, miss); |
| 432 } | 430 } |
| 433 | 431 |
| 434 | 432 |
| 435 // Generate StoreTransition code, value is passed in x0 register. | 433 // Generate StoreTransition code, value is passed in x0 register. |
| 436 // When leaving generated code after success, the receiver_reg and name_reg may | 434 // When leaving generated code after success, the receiver_reg and name_reg may |
| 437 // be clobbered. Upon branch to miss_label, the receiver and name registers have | 435 // be clobbered. Upon branch to miss_label, the receiver and name registers have |
| 438 // their original values. | 436 // their original values. |
| 439 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, | 437 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 GenerateDictionaryNegativeLookup( | 507 GenerateDictionaryNegativeLookup( |
| 510 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); | 508 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); |
| 511 } | 509 } |
| 512 } | 510 } |
| 513 } | 511 } |
| 514 | 512 |
| 515 // We've possibly already clobbered name_reg at this point, so use it for | 513 // We've possibly already clobbered name_reg at this point, so use it for |
| 516 // storage_reg. | 514 // storage_reg. |
| 517 Register storage_reg = name_reg; | 515 Register storage_reg = name_reg; |
| 518 | 516 |
| 519 if (FLAG_track_fields && representation.IsSmi()) { | 517 if (details.type() == CONSTANT_FUNCTION) { |
| 518 Handle<HeapObject> constant( |
| 519 HeapObject::cast(descriptors->GetValue(descriptor))); |
| 520 __ LoadHeapObject(scratch1, constant); |
| 521 __ Cmp(value_reg, scratch1); |
| 522 __ B(ne, miss_restore_name); |
| 523 } else if (FLAG_track_fields && representation.IsSmi()) { |
| 520 __ JumpIfNotSmi(value_reg, miss_restore_name); | 524 __ JumpIfNotSmi(value_reg, miss_restore_name); |
| 521 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 525 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| 522 __ JumpIfSmi(value_reg, miss_restore_name); | 526 __ JumpIfSmi(value_reg, miss_restore_name); |
| 523 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 527 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| 524 Label do_store, heap_number; | 528 Label do_store, heap_number; |
| 525 __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2); | 529 __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2); |
| 526 | 530 |
| 527 // TODO(jbramley): Is fp_scratch the most appropriate FP scratch register? | 531 // TODO(jbramley): Is fp_scratch the most appropriate FP scratch register? |
| 528 // It's only used in Fcmp, but it's not really safe to use it like this. | 532 // It's only used in Fcmp, but it's not really safe to use it like this. |
| 529 __ JumpIfNotSmi(value_reg, &heap_number); | 533 __ JumpIfNotSmi(value_reg, &heap_number); |
| 530 __ SmiUntagToDouble(fp_scratch, value_reg); | 534 __ SmiUntagToDouble(fp_scratch, value_reg); |
| 531 __ B(&do_store); | 535 __ B(&do_store); |
| 532 | 536 |
| 533 __ Bind(&heap_number); | 537 __ Bind(&heap_number); |
| 534 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, | 538 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, |
| 535 miss_restore_name, DONT_DO_SMI_CHECK); | 539 miss_restore_name, DONT_DO_SMI_CHECK); |
| 536 __ Ldr(fp_scratch, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); | 540 __ Ldr(fp_scratch, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); |
| 537 | 541 |
| 538 __ Bind(&do_store); | 542 __ Bind(&do_store); |
| 539 __ Str(fp_scratch, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); | 543 __ Str(fp_scratch, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); |
| 540 } | 544 } |
| 541 | 545 |
| 542 // Stub never generated for non-global objects that require access checks. | 546 // Stub never generated for non-global objects that require access checks. |
| 543 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 547 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
| 544 | 548 |
| 545 // Perform map transition for the receiver if necessary. | 549 // Perform map transition for the receiver if necessary. |
| 546 if (object->map()->unused_property_fields() == 0) { | 550 if ((details.type() == FIELD) && |
| 551 (object->map()->unused_property_fields() == 0)) { |
| 547 // The properties must be extended before we can store the value. | 552 // The properties must be extended before we can store the value. |
| 548 // We jump to a runtime call that extends the properties array. | 553 // We jump to a runtime call that extends the properties array. |
| 549 __ Mov(scratch1, Operand(transition)); | 554 __ Mov(scratch1, Operand(transition)); |
| 550 __ Push(receiver_reg, scratch1, value_reg); | 555 __ Push(receiver_reg, scratch1, value_reg); |
| 551 __ TailCallExternalReference( | 556 __ TailCallExternalReference( |
| 552 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 557 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
| 553 masm->isolate()), | 558 masm->isolate()), |
| 554 3, | 559 3, |
| 555 1); | 560 1); |
| 556 return; | 561 return; |
| 557 } | 562 } |
| 558 | 563 |
| 559 // Update the map of the object. | 564 // Update the map of the object. |
| 560 __ Mov(scratch1, Operand(transition)); | 565 __ Mov(scratch1, Operand(transition)); |
| 561 __ Str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); | 566 __ Str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
| 562 | 567 |
| 563 // Update the write barrier for the map field and pass the now unused | 568 // Update the write barrier for the map field and pass the now unused |
| 564 // name_reg as scratch register. | 569 // name_reg as scratch register. |
| 565 __ RecordWriteField(receiver_reg, | 570 __ RecordWriteField(receiver_reg, |
| 566 HeapObject::kMapOffset, | 571 HeapObject::kMapOffset, |
| 567 scratch1, | 572 scratch1, |
| 568 scratch2, | 573 scratch2, |
| 569 kLRHasNotBeenSaved, | 574 kLRHasNotBeenSaved, |
| 570 kDontSaveFPRegs, | 575 kDontSaveFPRegs, |
| 571 OMIT_REMEMBERED_SET, | 576 OMIT_REMEMBERED_SET, |
| 572 OMIT_SMI_CHECK); | 577 OMIT_SMI_CHECK); |
| 578 |
| 579 if (details.type() == CONSTANT_FUNCTION) { |
| 580 ASSERT(value_reg.is(x0)); |
| 581 __ Ret(); |
| 582 return; |
| 583 } |
| 584 |
| 573 int index = transition->instance_descriptors()->GetFieldIndex( | 585 int index = transition->instance_descriptors()->GetFieldIndex( |
| 574 transition->LastAdded()); | 586 transition->LastAdded()); |
| 575 | 587 |
| 576 // Adjust for the number of properties stored in the object. Even in the | 588 // Adjust for the number of properties stored in the object. Even in the |
| 577 // face of a transition we can use the old map here because the size of the | 589 // face of a transition we can use the old map here because the size of the |
| 578 // object and the number of in-object properties is not going to change. | 590 // object and the number of in-object properties is not going to change. |
| 579 index -= object->map()->inobject_properties(); | 591 index -= object->map()->inobject_properties(); |
| 580 | 592 |
| 581 // TODO(verwaest): Share this code as a code stub. | 593 // TODO(verwaest): Share this code as a code stub. |
| 582 SmiCheck smi_check = representation.IsTagged() | 594 SmiCheck smi_check = representation.IsTagged() |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 | 1013 |
| 1002 Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 1014 Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
| 1003 bool returns_handle = | 1015 bool returns_handle = |
| 1004 !CallbackTable::ReturnsVoid(masm->isolate(), function_address); | 1016 !CallbackTable::ReturnsVoid(masm->isolate(), function_address); |
| 1005 ApiFunction fun(function_address); | 1017 ApiFunction fun(function_address); |
| 1006 ExternalReference::Type type = | 1018 ExternalReference::Type type = |
| 1007 returns_handle ? | 1019 returns_handle ? |
| 1008 ExternalReference::DIRECT_API_CALL : | 1020 ExternalReference::DIRECT_API_CALL : |
| 1009 ExternalReference::DIRECT_API_CALL_NEW; | 1021 ExternalReference::DIRECT_API_CALL_NEW; |
| 1010 ExternalReference ref = ExternalReference(&fun, type, masm->isolate()); | 1022 ExternalReference ref = ExternalReference(&fun, type, masm->isolate()); |
| 1023 |
| 1024 Address thunk_address = |
| 1025 returns_handle ? |
| 1026 FUNCTION_ADDR(&InvokeInvocationCallback) : |
| 1027 FUNCTION_ADDR(&InvokeFunctionCallback); |
| 1028 ExternalReference::Type thunk_type = |
| 1029 returns_handle ? |
| 1030 ExternalReference::PROFILING_API_CALL : |
| 1031 ExternalReference::PROFILING_API_CALL_NEW; |
| 1032 ApiFunction thunk_fun(thunk_address); |
| 1033 ExternalReference thunk_ref = |
| 1034 ExternalReference(&thunk_fun, thunk_type, masm->isolate()); |
| 1035 |
| 1011 AllowExternalCallThatCantCauseGC scope(masm); | 1036 AllowExternalCallThatCantCauseGC scope(masm); |
| 1012 // CallApiFunctionAndReturn can spill registers inside the exit frame, | 1037 // CallApiFunctionAndReturn can spill registers inside the exit frame, |
| 1013 // after the return address and the v8::Arguments structure. | 1038 // after the return address and the v8::Arguments structure. |
| 1014 const int spill_offset = 1 + kApiArgsStackSpace; | 1039 const int spill_offset = 1 + kApiArgsStackSpace; |
| 1015 __ CallApiFunctionAndReturn(ref, | 1040 __ CallApiFunctionAndReturn(ref, |
| 1041 function_address, |
| 1042 thunk_ref, |
| 1043 x1, |
| 1016 kStackUnwindSpace, | 1044 kStackUnwindSpace, |
| 1017 spill_offset, | 1045 spill_offset, |
| 1018 returns_handle, | 1046 returns_handle, |
| 1019 kFastApiCallArguments + 1); | 1047 kFastApiCallArguments + 1); |
| 1020 } | 1048 } |
| 1021 | 1049 |
| 1022 | 1050 |
| 1023 class CallInterceptorCompiler BASE_EMBEDDED { | 1051 class CallInterceptorCompiler BASE_EMBEDDED { |
| 1024 public: | 1052 public: |
| 1025 CallInterceptorCompiler(StubCompiler* stub_compiler, | 1053 CallInterceptorCompiler(StubCompiler* stub_compiler, |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1495 // - the property name | 1523 // - the property name |
| 1496 // - the receiver. | 1524 // - the receiver. |
| 1497 // | 1525 // |
| 1498 // The memory allocated inside the ExitFrame will be freed when we'll leave | 1526 // The memory allocated inside the ExitFrame will be freed when we'll leave |
| 1499 // the ExitFrame in CallApiFunctionAndReturn. | 1527 // the ExitFrame in CallApiFunctionAndReturn. |
| 1500 const int kStackUnwindSpace = kFastApiCallArguments + 1; | 1528 const int kStackUnwindSpace = kFastApiCallArguments + 1; |
| 1501 | 1529 |
| 1502 // Do the API call. | 1530 // Do the API call. |
| 1503 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1531 Address getter_address = v8::ToCData<Address>(callback->getter()); |
| 1504 bool returns_handle = !CallbackTable::ReturnsVoid(isolate(), getter_address); | 1532 bool returns_handle = !CallbackTable::ReturnsVoid(isolate(), getter_address); |
| 1533 |
| 1505 ApiFunction fun(getter_address); | 1534 ApiFunction fun(getter_address); |
| 1506 ExternalReference::Type type = | 1535 ExternalReference::Type type = |
| 1507 returns_handle ? | 1536 returns_handle ? |
| 1508 ExternalReference::DIRECT_GETTER_CALL : | 1537 ExternalReference::DIRECT_GETTER_CALL : |
| 1509 ExternalReference::DIRECT_GETTER_CALL_NEW; | 1538 ExternalReference::DIRECT_GETTER_CALL_NEW; |
| 1510 ExternalReference ref = ExternalReference(&fun, type, isolate()); | 1539 ExternalReference ref = ExternalReference(&fun, type, isolate()); |
| 1540 |
| 1541 Address thunk_address = returns_handle |
| 1542 ? FUNCTION_ADDR(&InvokeAccessorGetter) |
| 1543 : FUNCTION_ADDR(&InvokeAccessorGetterCallback); |
| 1544 ExternalReference::Type thunk_type = |
| 1545 returns_handle ? |
| 1546 ExternalReference::PROFILING_GETTER_CALL : |
| 1547 ExternalReference::PROFILING_GETTER_CALL_NEW; |
| 1548 ApiFunction thunk_fun(thunk_address); |
| 1549 ExternalReference thunk_ref = |
| 1550 ExternalReference(&thunk_fun, thunk_type, isolate()); |
| 1551 |
| 1511 // TODO(jbramley): I don't know where '5' comes from, but this goes away at | 1552 // TODO(jbramley): I don't know where '5' comes from, but this goes away at |
| 1512 // some point. | 1553 // some point. |
| 1513 __ CallApiFunctionAndReturn(ref, | 1554 __ CallApiFunctionAndReturn(ref, |
| 1555 getter_address, |
| 1556 thunk_ref, |
| 1557 x2, |
| 1514 kStackUnwindSpace, | 1558 kStackUnwindSpace, |
| 1515 spill_offset, | 1559 spill_offset, |
| 1516 returns_handle, | 1560 returns_handle, |
| 1517 5); | 1561 5); |
| 1518 } | 1562 } |
| 1519 | 1563 |
| 1520 | 1564 |
| 1521 void BaseLoadStubCompiler::GenerateLoadInterceptor( | 1565 void BaseLoadStubCompiler::GenerateLoadInterceptor( |
| 1522 Register holder_reg, | 1566 Register holder_reg, |
| 1523 Handle<JSObject> object, | 1567 Handle<JSObject> object, |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1631 __ Peek(receiver, argc * kPointerSize); | 1675 __ Peek(receiver, argc * kPointerSize); |
| 1632 | 1676 |
| 1633 // Check that the maps haven't changed. | 1677 // Check that the maps haven't changed. |
| 1634 __ JumpIfSmi(receiver, miss); | 1678 __ JumpIfSmi(receiver, miss); |
| 1635 CheckPrototypes(object, receiver, holder, x3, x1, x4, name, miss); | 1679 CheckPrototypes(object, receiver, holder, x3, x1, x4, name, miss); |
| 1636 } | 1680 } |
| 1637 | 1681 |
| 1638 | 1682 |
| 1639 // Load the function object into x1 register. | 1683 // Load the function object into x1 register. |
| 1640 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1684 void CallStubCompiler::GenerateLoadFunctionFromCell( |
| 1641 Handle<JSGlobalPropertyCell> cell, | 1685 Handle<Cell> cell, |
| 1642 Handle<JSFunction> function, | 1686 Handle<JSFunction> function, |
| 1643 Label* miss) { | 1687 Label* miss) { |
| 1644 // Get the value from the cell. | 1688 // Get the value from the cell. |
| 1645 __ Mov(x3, Operand(cell)); | 1689 __ Mov(x3, Operand(cell)); |
| 1646 Register function_reg = x1; | 1690 Register function_reg = x1; |
| 1647 __ Ldr(function_reg, FieldMemOperand(x3, JSGlobalPropertyCell::kValueOffset)); | 1691 __ Ldr(function_reg, FieldMemOperand(x3, Cell::kValueOffset)); |
| 1648 | 1692 |
| 1649 // Check that the cell contains the same function. | 1693 // Check that the cell contains the same function. |
| 1650 if (heap()->InNewSpace(*function)) { | 1694 if (heap()->InNewSpace(*function)) { |
| 1651 // We can't embed a pointer to a function in new space so we have | 1695 // We can't embed a pointer to a function in new space so we have |
| 1652 // to verify that the shared function info is unchanged. This has | 1696 // to verify that the shared function info is unchanged. This has |
| 1653 // the nice side effect that multiple closures based on the same | 1697 // the nice side effect that multiple closures based on the same |
| 1654 // function can all use this call IC. Before we load through the | 1698 // function can all use this call IC. Before we load through the |
| 1655 // function, we have to verify that it still is a function. | 1699 // function, we have to verify that it still is a function. |
| 1656 __ JumpIfSmi(function_reg, miss); | 1700 __ JumpIfSmi(function_reg, miss); |
| 1657 __ JumpIfNotObjectType(function_reg, x3, x3, JS_FUNCTION_TYPE, miss); | 1701 __ JumpIfNotObjectType(function_reg, x3, x3, JS_FUNCTION_TYPE, miss); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1710 | 1754 |
| 1711 // Handle call cache miss. | 1755 // Handle call cache miss. |
| 1712 __ Bind(&miss); | 1756 __ Bind(&miss); |
| 1713 GenerateMissBranch(); | 1757 GenerateMissBranch(); |
| 1714 | 1758 |
| 1715 // Return the generated code. | 1759 // Return the generated code. |
| 1716 return GetCode(Code::FIELD, name); | 1760 return GetCode(Code::FIELD, name); |
| 1717 } | 1761 } |
| 1718 | 1762 |
| 1719 | 1763 |
| 1764 Handle<Code> CallStubCompiler::CompileArrayCodeCall( |
| 1765 Handle<Object> object, |
| 1766 Handle<JSObject> holder, |
| 1767 Handle<Cell> cell, |
| 1768 Handle<JSFunction> function, |
| 1769 Handle<String> name, |
| 1770 Code::StubType type) { |
| 1771 // ----------- S t a t e ------------- |
| 1772 // -- x2 : name |
| 1773 // -- lr : return address |
| 1774 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) |
| 1775 // -- ... |
| 1776 // -- sp[argc * 8] : receiver |
| 1777 // ----------------------------------- |
| 1778 Label miss; |
| 1779 |
| 1780 // Check that function is still array. |
| 1781 const int argc = arguments().immediate(); |
| 1782 GenerateNameCheck(name, &miss); |
| 1783 |
| 1784 Register receiver = x1; |
| 1785 if (cell.is_null()) { |
| 1786 __ Peek(receiver, argc * kPointerSize); |
| 1787 |
| 1788 // Check that the receiver isn't a smi. |
| 1789 __ JumpIfSmi(receiver, &miss); |
| 1790 |
| 1791 // Check that the maps haven't changed. |
| 1792 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, x3, x0, |
| 1793 x4, name, &miss); |
| 1794 } else { |
| 1795 ASSERT(cell->value() == *function); |
| 1796 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 1797 &miss); |
| 1798 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1799 } |
| 1800 |
| 1801 Handle<Smi> kind(Smi::FromInt(GetInitialFastElementsKind()), isolate()); |
| 1802 Handle<Cell> kind_feedback_cell = isolate()->factory()->NewCell(kind); |
| 1803 __ Mov(x0, argc); |
| 1804 __ Mov(x1, Operand(function)); |
| 1805 __ Mov(x2, Operand(kind_feedback_cell)); |
| 1806 |
| 1807 ArrayConstructorStub stub(isolate()); |
| 1808 __ TailCallStub(&stub); |
| 1809 |
| 1810 __ Bind(&miss); |
| 1811 GenerateMissBranch(); |
| 1812 |
| 1813 // Return the generated code. |
| 1814 return GetCode(type, name); |
| 1815 } |
| 1816 |
| 1817 |
| 1720 Handle<Code> CallStubCompiler::CompileArrayPushCall( | 1818 Handle<Code> CallStubCompiler::CompileArrayPushCall( |
| 1721 Handle<Object> object, | 1819 Handle<Object> object, |
| 1722 Handle<JSObject> holder, | 1820 Handle<JSObject> holder, |
| 1723 Handle<JSGlobalPropertyCell> cell, | 1821 Handle<Cell> cell, |
| 1724 Handle<JSFunction> function, | 1822 Handle<JSFunction> function, |
| 1725 Handle<String> name) { | 1823 Handle<String> name, |
| 1824 Code::StubType type) { |
| 1726 // ----------- S t a t e ------------- | 1825 // ----------- S t a t e ------------- |
| 1727 // -- x2 : name (Must be preserved on miss.) | 1826 // -- x2 : name (Must be preserved on miss.) |
| 1728 // -- lr : return address | 1827 // -- lr : return address |
| 1729 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) | 1828 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) |
| 1730 // -- ... | 1829 // -- ... |
| 1731 // -- sp[argc * 8] : receiver | 1830 // -- sp[argc * 8] : receiver |
| 1732 // ----------------------------------- | 1831 // ----------------------------------- |
| 1733 | 1832 |
| 1734 // If object is not an array, bail out to regular call. | 1833 // If object is not an array, bail out to regular call. |
| 1735 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); | 1834 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1975 __ Bind(&call_builtin); | 2074 __ Bind(&call_builtin); |
| 1976 __ TailCallExternalReference( | 2075 __ TailCallExternalReference( |
| 1977 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); | 2076 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); |
| 1978 } | 2077 } |
| 1979 | 2078 |
| 1980 // Handle call cache miss. | 2079 // Handle call cache miss. |
| 1981 __ Bind(&miss); | 2080 __ Bind(&miss); |
| 1982 GenerateMissBranch(); | 2081 GenerateMissBranch(); |
| 1983 | 2082 |
| 1984 // Return the generated code. | 2083 // Return the generated code. |
| 1985 return GetCode(function); | 2084 return GetCode(type, name); |
| 1986 } | 2085 } |
| 1987 | 2086 |
| 1988 | 2087 |
| 1989 Handle<Code> CallStubCompiler::CompileArrayPopCall( | 2088 Handle<Code> CallStubCompiler::CompileArrayPopCall( |
| 1990 Handle<Object> object, | 2089 Handle<Object> object, |
| 1991 Handle<JSObject> holder, | 2090 Handle<JSObject> holder, |
| 1992 Handle<JSGlobalPropertyCell> cell, | 2091 Handle<Cell> cell, |
| 1993 Handle<JSFunction> function, | 2092 Handle<JSFunction> function, |
| 1994 Handle<String> name) { | 2093 Handle<String> name, |
| 2094 Code::StubType type) { |
| 1995 // ----------- S t a t e ------------- | 2095 // ----------- S t a t e ------------- |
| 1996 // -- x2 : name | 2096 // -- x2 : name |
| 1997 // -- lr : return address | 2097 // -- lr : return address |
| 1998 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) | 2098 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) |
| 1999 // -- ... | 2099 // -- ... |
| 2000 // -- sp[argc * 8] : receiver | 2100 // -- sp[argc * 8] : receiver |
| 2001 // ----------------------------------- | 2101 // ----------------------------------- |
| 2002 | 2102 |
| 2003 // If object is not an array, bail out to regular call. | 2103 // If object is not an array, bail out to regular call. |
| 2004 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); | 2104 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2059 | 2159 |
| 2060 __ Bind(&call_builtin); | 2160 __ Bind(&call_builtin); |
| 2061 __ TailCallExternalReference( | 2161 __ TailCallExternalReference( |
| 2062 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); | 2162 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); |
| 2063 | 2163 |
| 2064 // Handle call cache miss. | 2164 // Handle call cache miss. |
| 2065 __ Bind(&miss); | 2165 __ Bind(&miss); |
| 2066 GenerateMissBranch(); | 2166 GenerateMissBranch(); |
| 2067 | 2167 |
| 2068 // Return the generated code. | 2168 // Return the generated code. |
| 2069 return GetCode(function); | 2169 return GetCode(type, name); |
| 2070 } | 2170 } |
| 2071 | 2171 |
| 2072 | 2172 |
| 2073 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( | 2173 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( |
| 2074 Handle<Object> object, | 2174 Handle<Object> object, |
| 2075 Handle<JSObject> holder, | 2175 Handle<JSObject> holder, |
| 2076 Handle<JSGlobalPropertyCell> cell, | 2176 Handle<Cell> cell, |
| 2077 Handle<JSFunction> function, | 2177 Handle<JSFunction> function, |
| 2078 Handle<String> name) { | 2178 Handle<String> name, |
| 2179 Code::StubType type) { |
| 2079 // ----------- S t a t e ------------- | 2180 // ----------- S t a t e ------------- |
| 2080 // -- x2 : function name | 2181 // -- x2 : function name |
| 2081 // -- lr : return address | 2182 // -- lr : return address |
| 2082 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) | 2183 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) |
| 2083 // -- ... | 2184 // -- ... |
| 2084 // -- sp[argc * 8] : receiver | 2185 // -- sp[argc * 8] : receiver |
| 2085 // ----------------------------------- | 2186 // ----------------------------------- |
| 2086 | 2187 |
| 2087 // If object is not a string, bail out to regular call. | 2188 // If object is not a string, bail out to regular call. |
| 2088 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); | 2189 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2143 __ Ret(); | 2244 __ Ret(); |
| 2144 } | 2245 } |
| 2145 | 2246 |
| 2146 __ Bind(&miss); | 2247 __ Bind(&miss); |
| 2147 // Restore function name in x2. | 2248 // Restore function name in x2. |
| 2148 __ Mov(x2, Operand(name)); | 2249 __ Mov(x2, Operand(name)); |
| 2149 __ Bind(&name_miss); | 2250 __ Bind(&name_miss); |
| 2150 GenerateMissBranch(); | 2251 GenerateMissBranch(); |
| 2151 | 2252 |
| 2152 // Return the generated code. | 2253 // Return the generated code. |
| 2153 return GetCode(function); | 2254 return GetCode(type, name); |
| 2154 } | 2255 } |
| 2155 | 2256 |
| 2156 | 2257 |
| 2157 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 2258 Handle<Code> CallStubCompiler::CompileStringCharAtCall( |
| 2158 Handle<Object> object, | 2259 Handle<Object> object, |
| 2159 Handle<JSObject> holder, | 2260 Handle<JSObject> holder, |
| 2160 Handle<JSGlobalPropertyCell> cell, | 2261 Handle<Cell> cell, |
| 2161 Handle<JSFunction> function, | 2262 Handle<JSFunction> function, |
| 2162 Handle<String> name) { | 2263 Handle<String> name, |
| 2264 Code::StubType type) { |
| 2163 // ----------- S t a t e ------------- | 2265 // ----------- S t a t e ------------- |
| 2164 // -- x2 : function name | 2266 // -- x2 : function name |
| 2165 // -- lr : return address | 2267 // -- lr : return address |
| 2166 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) | 2268 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) |
| 2167 // -- ... | 2269 // -- ... |
| 2168 // -- sp[argc * 8] : receiver | 2270 // -- sp[argc * 8] : receiver |
| 2169 // ----------------------------------- | 2271 // ----------------------------------- |
| 2170 | 2272 |
| 2171 // If object is not a string, bail out to regular call. | 2273 // If object is not a string, bail out to regular call. |
| 2172 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); | 2274 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2229 __ Ret(); | 2331 __ Ret(); |
| 2230 } | 2332 } |
| 2231 | 2333 |
| 2232 __ Bind(&miss); | 2334 __ Bind(&miss); |
| 2233 // Restore function name in x2. | 2335 // Restore function name in x2. |
| 2234 __ Mov(x2, Operand(name)); | 2336 __ Mov(x2, Operand(name)); |
| 2235 __ Bind(&name_miss); | 2337 __ Bind(&name_miss); |
| 2236 GenerateMissBranch(); | 2338 GenerateMissBranch(); |
| 2237 | 2339 |
| 2238 // Return the generated code. | 2340 // Return the generated code. |
| 2239 return GetCode(function); | 2341 return GetCode(type, name); |
| 2240 } | 2342 } |
| 2241 | 2343 |
| 2242 | 2344 |
| 2243 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 2345 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( |
| 2244 Handle<Object> object, | 2346 Handle<Object> object, |
| 2245 Handle<JSObject> holder, | 2347 Handle<JSObject> holder, |
| 2246 Handle<JSGlobalPropertyCell> cell, | 2348 Handle<Cell> cell, |
| 2247 Handle<JSFunction> function, | 2349 Handle<JSFunction> function, |
| 2248 Handle<String> name) { | 2350 Handle<String> name, |
| 2351 Code::StubType type) { |
| 2249 // ----------- S t a t e ------------- | 2352 // ----------- S t a t e ------------- |
| 2250 // -- x2 : function name | 2353 // -- x2 : function name |
| 2251 // -- lr : return address | 2354 // -- lr : return address |
| 2252 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) | 2355 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) |
| 2253 // -- ... | 2356 // -- ... |
| 2254 // -- sp[argc * 8] : receiver | 2357 // -- sp[argc * 8] : receiver |
| 2255 // ----------------------------------- | 2358 // ----------------------------------- |
| 2256 const int argc = arguments().immediate(); | 2359 const int argc = arguments().immediate(); |
| 2257 | 2360 |
| 2258 // If the object is not a JSObject or we got an unexpected number of | 2361 // If the object is not a JSObject or we got an unexpected number of |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2300 // because the function makes no use of it. | 2403 // because the function makes no use of it. |
| 2301 __ Bind(&slow); | 2404 __ Bind(&slow); |
| 2302 ParameterCount expected(function); | 2405 ParameterCount expected(function); |
| 2303 __ InvokeFunction(function, expected, arguments(), | 2406 __ InvokeFunction(function, expected, arguments(), |
| 2304 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2407 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2305 | 2408 |
| 2306 __ Bind(&miss); | 2409 __ Bind(&miss); |
| 2307 GenerateMissBranch(); | 2410 GenerateMissBranch(); |
| 2308 | 2411 |
| 2309 // Return the generated code. | 2412 // Return the generated code. |
| 2310 return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); | 2413 return GetCode(type, name); |
| 2311 } | 2414 } |
| 2312 | 2415 |
| 2313 | 2416 |
| 2314 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 2417 Handle<Code> CallStubCompiler::CompileMathFloorCall( |
| 2315 Handle<Object> object, | 2418 Handle<Object> object, |
| 2316 Handle<JSObject> holder, | 2419 Handle<JSObject> holder, |
| 2317 Handle<JSGlobalPropertyCell> cell, | 2420 Handle<Cell> cell, |
| 2318 Handle<JSFunction> function, | 2421 Handle<JSFunction> function, |
| 2319 Handle<String> name) { | 2422 Handle<String> name, |
| 2423 Code::StubType type) { |
| 2320 // ----------- S t a t e ------------- | 2424 // ----------- S t a t e ------------- |
| 2321 // -- x2 : function name (must be preserved on miss) | 2425 // -- x2 : function name (must be preserved on miss) |
| 2322 // -- lr : return address | 2426 // -- lr : return address |
| 2323 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) | 2427 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) |
| 2324 // -- ... | 2428 // -- ... |
| 2325 // -- sp[argc * 8] : receiver | 2429 // -- sp[argc * 8] : receiver |
| 2326 // ----------------------------------- | 2430 // ----------------------------------- |
| 2327 Label miss; | 2431 Label miss; |
| 2328 Label return_result; | 2432 Label return_result; |
| 2329 Register result = x0; | 2433 Register result = x0; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2415 // Tail call the full function. We do not have to patch the receiver | 2519 // Tail call the full function. We do not have to patch the receiver |
| 2416 // because the function makes no use of it. | 2520 // because the function makes no use of it. |
| 2417 ParameterCount expected(function); | 2521 ParameterCount expected(function); |
| 2418 __ InvokeFunction(function, expected, arguments(), | 2522 __ InvokeFunction(function, expected, arguments(), |
| 2419 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2523 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2420 | 2524 |
| 2421 __ Bind(&miss); | 2525 __ Bind(&miss); |
| 2422 GenerateMissBranch(); | 2526 GenerateMissBranch(); |
| 2423 | 2527 |
| 2424 // Return the generated code. | 2528 // Return the generated code. |
| 2425 return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); | 2529 return GetCode(type, name); |
| 2426 } | 2530 } |
| 2427 | 2531 |
| 2428 | 2532 |
| 2429 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 2533 Handle<Code> CallStubCompiler::CompileMathAbsCall( |
| 2430 Handle<Object> object, | 2534 Handle<Object> object, |
| 2431 Handle<JSObject> holder, | 2535 Handle<JSObject> holder, |
| 2432 Handle<JSGlobalPropertyCell> cell, | 2536 Handle<Cell> cell, |
| 2433 Handle<JSFunction> function, | 2537 Handle<JSFunction> function, |
| 2434 Handle<String> name) { | 2538 Handle<String> name, |
| 2539 Code::StubType type) { |
| 2435 // ----------- S t a t e ------------- | 2540 // ----------- S t a t e ------------- |
| 2436 // -- x2 : function name | 2541 // -- x2 : function name |
| 2437 // -- lr : return address | 2542 // -- lr : return address |
| 2438 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) | 2543 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) |
| 2439 // -- ... | 2544 // -- ... |
| 2440 // -- sp[argc * 8] : receiver | 2545 // -- sp[argc * 8] : receiver |
| 2441 // ----------------------------------- | 2546 // ----------------------------------- |
| 2442 | 2547 |
| 2443 const int argc = arguments().immediate(); | 2548 const int argc = arguments().immediate(); |
| 2444 | 2549 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2501 // because the function makes no use of it. | 2606 // because the function makes no use of it. |
| 2502 __ Bind(&slow); | 2607 __ Bind(&slow); |
| 2503 ParameterCount expected(function); | 2608 ParameterCount expected(function); |
| 2504 __ InvokeFunction(function, expected, arguments(), | 2609 __ InvokeFunction(function, expected, arguments(), |
| 2505 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2610 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2506 | 2611 |
| 2507 __ Bind(&miss); | 2612 __ Bind(&miss); |
| 2508 GenerateMissBranch(); | 2613 GenerateMissBranch(); |
| 2509 | 2614 |
| 2510 // Return the generated code. | 2615 // Return the generated code. |
| 2511 return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); | 2616 return GetCode(type, name); |
| 2512 } | 2617 } |
| 2513 | 2618 |
| 2514 | 2619 |
| 2515 Handle<Code> CallStubCompiler::CompileFastApiCall( | 2620 Handle<Code> CallStubCompiler::CompileFastApiCall( |
| 2516 const CallOptimization& optimization, | 2621 const CallOptimization& optimization, |
| 2517 Handle<Object> object, | 2622 Handle<Object> object, |
| 2518 Handle<JSObject> holder, | 2623 Handle<JSObject> holder, |
| 2519 Handle<JSGlobalPropertyCell> cell, | 2624 Handle<Cell> cell, |
| 2520 Handle<JSFunction> function, | 2625 Handle<JSFunction> function, |
| 2521 Handle<String> name) { | 2626 Handle<String> name) { |
| 2522 Counters* counters = isolate()->counters(); | 2627 Counters* counters = isolate()->counters(); |
| 2523 | 2628 |
| 2524 ASSERT(optimization.is_simple_api_call()); | 2629 ASSERT(optimization.is_simple_api_call()); |
| 2525 // Bail out if object is a global object as we don't want to | 2630 // Bail out if object is a global object as we don't want to |
| 2526 // repatch it to global receiver. | 2631 // repatch it to global receiver. |
| 2527 if (object->IsGlobalObject()) return Handle<Code>::null(); | 2632 if (object->IsGlobalObject()) return Handle<Code>::null(); |
| 2528 if (!cell.is_null()) return Handle<Code>::null(); | 2633 if (!cell.is_null()) return Handle<Code>::null(); |
| 2529 if (!object->IsJSObject()) return Handle<Code>::null(); | 2634 if (!object->IsJSObject()) return Handle<Code>::null(); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2684 | 2789 |
| 2685 | 2790 |
| 2686 Handle<Code> CallStubCompiler::CompileCallConstant( | 2791 Handle<Code> CallStubCompiler::CompileCallConstant( |
| 2687 Handle<Object> object, | 2792 Handle<Object> object, |
| 2688 Handle<JSObject> holder, | 2793 Handle<JSObject> holder, |
| 2689 Handle<Name> name, | 2794 Handle<Name> name, |
| 2690 CheckType check, | 2795 CheckType check, |
| 2691 Handle<JSFunction> function) { | 2796 Handle<JSFunction> function) { |
| 2692 if (HasCustomCallGenerator(function)) { | 2797 if (HasCustomCallGenerator(function)) { |
| 2693 Handle<Code> code = CompileCustomCall(object, holder, | 2798 Handle<Code> code = CompileCustomCall(object, holder, |
| 2694 Handle<JSGlobalPropertyCell>::null(), | 2799 Handle<Cell>::null(), |
| 2695 function, Handle<String>::cast(name)); | 2800 function, Handle<String>::cast(name), |
| 2801 Code::CONSTANT_FUNCTION); |
| 2696 // A null handle means bail out to the regular compiler code below. | 2802 // A null handle means bail out to the regular compiler code below. |
| 2697 if (!code.is_null()) return code; | 2803 if (!code.is_null()) return code; |
| 2698 } | 2804 } |
| 2699 | 2805 |
| 2700 Label success; | 2806 Label success; |
| 2701 | 2807 |
| 2702 CompileHandlerFrontend(object, holder, name, check, &success); | 2808 CompileHandlerFrontend(object, holder, name, check, &success); |
| 2703 __ Bind(&success); | 2809 __ Bind(&success); |
| 2704 CompileHandlerBackend(function); | 2810 CompileHandlerBackend(function); |
| 2705 | 2811 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2748 GenerateMissBranch(); | 2854 GenerateMissBranch(); |
| 2749 | 2855 |
| 2750 // Return the generated code. | 2856 // Return the generated code. |
| 2751 return GetCode(Code::INTERCEPTOR, name); | 2857 return GetCode(Code::INTERCEPTOR, name); |
| 2752 } | 2858 } |
| 2753 | 2859 |
| 2754 | 2860 |
| 2755 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2861 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2756 Handle<JSObject> object, | 2862 Handle<JSObject> object, |
| 2757 Handle<GlobalObject> holder, | 2863 Handle<GlobalObject> holder, |
| 2758 Handle<JSGlobalPropertyCell> cell, | 2864 Handle<PropertyCell> cell, |
| 2759 Handle<JSFunction> function, | 2865 Handle<JSFunction> function, |
| 2760 Handle<Name> name) { | 2866 Handle<Name> name) { |
| 2761 // ----------- S t a t e ------------- | 2867 // ----------- S t a t e ------------- |
| 2762 // -- x2 : name | 2868 // -- x2 : name |
| 2763 // -- lr : return address | 2869 // -- lr : return address |
| 2764 // ----------------------------------- | 2870 // ----------------------------------- |
| 2765 if (HasCustomCallGenerator(function)) { | 2871 if (HasCustomCallGenerator(function)) { |
| 2766 Handle<Code> code = CompileCustomCall( | 2872 Handle<Code> code = CompileCustomCall( |
| 2767 object, holder, cell, function, Handle<String>::cast(name)); | 2873 object, holder, cell, function, Handle<String>::cast(name), |
| 2874 Code::NORMAL); |
| 2768 // A null handle means bail out to the regular compiler code below. | 2875 // A null handle means bail out to the regular compiler code below. |
| 2769 if (!code.is_null()) return code; | 2876 if (!code.is_null()) return code; |
| 2770 } | 2877 } |
| 2771 | 2878 |
| 2772 Label miss; | 2879 Label miss; |
| 2773 GenerateNameCheck(name, &miss); | 2880 GenerateNameCheck(name, &miss); |
| 2774 | 2881 |
| 2775 // Get the number of arguments. | 2882 // Get the number of arguments. |
| 2776 const int argc = arguments().immediate(); | 2883 const int argc = arguments().immediate(); |
| 2777 | 2884 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2930 __ Bind(&miss); | 3037 __ Bind(&miss); |
| 2931 TailCallBuiltin(masm(), MissBuiltin(kind())); | 3038 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2932 | 3039 |
| 2933 // Return the generated code. | 3040 // Return the generated code. |
| 2934 return GetICCode(kind(), Code::INTERCEPTOR, name); | 3041 return GetICCode(kind(), Code::INTERCEPTOR, name); |
| 2935 } | 3042 } |
| 2936 | 3043 |
| 2937 | 3044 |
| 2938 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 3045 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
| 2939 Handle<GlobalObject> object, | 3046 Handle<GlobalObject> object, |
| 2940 Handle<JSGlobalPropertyCell> cell, | 3047 Handle<PropertyCell> cell, |
| 2941 Handle<Name> name) { | 3048 Handle<Name> name) { |
| 2942 Label miss; | 3049 Label miss; |
| 2943 | 3050 |
| 2944 ASM_LOCATION("StoreStubCompiler::CompileStoreGlobal"); | 3051 ASM_LOCATION("StoreStubCompiler::CompileStoreGlobal"); |
| 2945 | 3052 |
| 2946 // Check that the map of the global has not changed. | 3053 // Check that the map of the global has not changed. |
| 2947 __ Ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); | 3054 __ Ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); |
| 2948 __ Cmp(scratch1(), Operand(Handle<Map>(object->map()))); | 3055 __ Cmp(scratch1(), Operand(Handle<Map>(object->map()))); |
| 2949 __ B(ne, &miss); | 3056 __ B(ne, &miss); |
| 2950 | 3057 |
| 2951 // Check that the value in the cell is not the hole. If it is, this | 3058 // Check that the value in the cell is not the hole. If it is, this |
| 2952 // cell could have been deleted and reintroducing the global needs | 3059 // cell could have been deleted and reintroducing the global needs |
| 2953 // to update the property details in the property dictionary of the | 3060 // to update the property details in the property dictionary of the |
| 2954 // global object. We bail out to the runtime system to do that. | 3061 // global object. We bail out to the runtime system to do that. |
| 2955 __ Mov(scratch1(), Operand(cell)); | 3062 __ Mov(scratch1(), Operand(cell)); |
| 2956 __ Ldr(scratch2(), FieldMemOperand(scratch1(), | 3063 __ Ldr(scratch2(), FieldMemOperand(scratch1(), |
| 2957 JSGlobalPropertyCell::kValueOffset)); | 3064 Cell::kValueOffset)); |
| 2958 __ JumpIfRoot(scratch2(), Heap::kTheHoleValueRootIndex, &miss); | 3065 __ JumpIfRoot(scratch2(), Heap::kTheHoleValueRootIndex, &miss); |
| 2959 | 3066 |
| 2960 // Store the value in the cell. | 3067 // Store the value in the cell. |
| 2961 __ Str(value(), FieldMemOperand(scratch1(), | 3068 __ Str(value(), FieldMemOperand(scratch1(), |
| 2962 JSGlobalPropertyCell::kValueOffset)); | 3069 Cell::kValueOffset)); |
| 2963 // Cells are always rescanned, so no write barrier here. | 3070 // Cells are always rescanned, so no write barrier here. |
| 2964 | 3071 |
| 2965 Counters* counters = isolate()->counters(); | 3072 Counters* counters = isolate()->counters(); |
| 2966 __ IncrementCounter(counters->named_store_global_inline(), 1, | 3073 __ IncrementCounter(counters->named_store_global_inline(), 1, |
| 2967 scratch1(), scratch2()); | 3074 scratch1(), scratch2()); |
| 2968 __ Ret(); | 3075 __ Ret(); |
| 2969 | 3076 |
| 2970 // Handle store cache miss. | 3077 // Handle store cache miss. |
| 2971 __ Bind(&miss); | 3078 __ Bind(&miss); |
| 2972 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, | 3079 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3079 } | 3186 } |
| 3080 | 3187 |
| 3081 | 3188 |
| 3082 #undef __ | 3189 #undef __ |
| 3083 #define __ ACCESS_MASM(masm()) | 3190 #define __ ACCESS_MASM(masm()) |
| 3084 | 3191 |
| 3085 | 3192 |
| 3086 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 3193 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
| 3087 Handle<JSObject> object, | 3194 Handle<JSObject> object, |
| 3088 Handle<GlobalObject> global, | 3195 Handle<GlobalObject> global, |
| 3089 Handle<JSGlobalPropertyCell> cell, | 3196 Handle<PropertyCell> cell, |
| 3090 Handle<Name> name, | 3197 Handle<Name> name, |
| 3091 bool is_dont_delete) { | 3198 bool is_dont_delete) { |
| 3092 Label success, miss; | 3199 Label success, miss; |
| 3093 | 3200 |
| 3094 __ CheckMap( | 3201 __ CheckMap( |
| 3095 receiver(), scratch1(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK); | 3202 receiver(), scratch1(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK); |
| 3096 HandlerFrontendHeader( | 3203 HandlerFrontendHeader( |
| 3097 object, receiver(), Handle<JSObject>::cast(global), name, &miss); | 3204 object, receiver(), Handle<JSObject>::cast(global), name, &miss); |
| 3098 | 3205 |
| 3099 // Get the value from the cell. | 3206 // Get the value from the cell. |
| 3100 __ Mov(x3, Operand(cell)); | 3207 __ Mov(x3, Operand(cell)); |
| 3101 __ Ldr(x4, FieldMemOperand(x3, JSGlobalPropertyCell::kValueOffset)); | 3208 __ Ldr(x4, FieldMemOperand(x3, Cell::kValueOffset)); |
| 3102 | 3209 |
| 3103 // Check for deleted property if property can actually be deleted. | 3210 // Check for deleted property if property can actually be deleted. |
| 3104 if (!is_dont_delete) { | 3211 if (!is_dont_delete) { |
| 3105 __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &miss); | 3212 __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &miss); |
| 3106 } | 3213 } |
| 3107 | 3214 |
| 3108 HandlerFrontendFooter(&success, &miss); | 3215 HandlerFrontendFooter(&success, &miss); |
| 3109 __ bind(&success); | 3216 __ bind(&success); |
| 3110 | 3217 |
| 3111 Counters* counters = isolate()->counters(); | 3218 Counters* counters = isolate()->counters(); |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3697 // ----------- S t a t e ------------- | 3804 // ----------- S t a t e ------------- |
| 3698 | 3805 |
| 3699 GenerateStoreFastSmiOrDoubleElement(masm, is_js_array, FAST_DOUBLE_ELEMENTS, | 3806 GenerateStoreFastSmiOrDoubleElement(masm, is_js_array, FAST_DOUBLE_ELEMENTS, |
| 3700 store_mode, true); | 3807 store_mode, true); |
| 3701 } | 3808 } |
| 3702 | 3809 |
| 3703 | 3810 |
| 3704 } } // namespace v8::internal | 3811 } } // namespace v8::internal |
| 3705 | 3812 |
| 3706 #endif // V8_TARGET_ARCH_A64 | 3813 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |