| 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 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 | 420 |
| 421 | 421 |
| 422 // Generate code to check that a global property cell is empty. Create | 422 // Generate code to check that a global property cell is empty. Create |
| 423 // the property cell at compilation time if no cell exists for the | 423 // the property cell at compilation time if no cell exists for the |
| 424 // property. | 424 // property. |
| 425 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 425 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 426 Handle<GlobalObject> global, | 426 Handle<GlobalObject> global, |
| 427 Handle<Name> name, | 427 Handle<Name> name, |
| 428 Register scratch, | 428 Register scratch, |
| 429 Label* miss) { | 429 Label* miss) { |
| 430 Handle<JSGlobalPropertyCell> cell = | 430 Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name); |
| 431 GlobalObject::EnsurePropertyCell(global, name); | |
| 432 ASSERT(cell->value()->IsTheHole()); | 431 ASSERT(cell->value()->IsTheHole()); |
| 433 __ mov(scratch, Operand(cell)); | 432 __ mov(scratch, Operand(cell)); |
| 434 __ ldr(scratch, | 433 __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); |
| 435 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | |
| 436 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 434 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 437 __ cmp(scratch, ip); | 435 __ cmp(scratch, ip); |
| 438 __ b(ne, miss); | 436 __ b(ne, miss); |
| 439 } | 437 } |
| 440 | 438 |
| 441 | 439 |
| 442 // Generate StoreTransition code, value is passed in r0 register. | 440 // Generate StoreTransition code, value is passed in r0 register. |
| 443 // When leaving generated code after success, the receiver_reg and name_reg | 441 // When leaving generated code after success, the receiver_reg and name_reg |
| 444 // may be clobbered. Upon branch to miss_label, the receiver and name | 442 // may be clobbered. Upon branch to miss_label, the receiver and name |
| 445 // registers have their original values. | 443 // registers have their original values. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 miss_restore_name); | 505 miss_restore_name); |
| 508 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { | 506 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { |
| 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 Register storage_reg = name_reg; | 513 Register storage_reg = name_reg; |
| 516 | 514 |
| 517 if (FLAG_track_fields && representation.IsSmi()) { | 515 if (details.type() == CONSTANT_FUNCTION) { |
| 516 Handle<HeapObject> constant( |
| 517 HeapObject::cast(descriptors->GetValue(descriptor))); |
| 518 __ LoadHeapObject(scratch1, constant); |
| 519 __ cmp(value_reg, scratch1); |
| 520 __ b(ne, miss_restore_name); |
| 521 } else if (FLAG_track_fields && representation.IsSmi()) { |
| 518 __ JumpIfNotSmi(value_reg, miss_restore_name); | 522 __ JumpIfNotSmi(value_reg, miss_restore_name); |
| 519 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 523 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| 520 __ JumpIfSmi(value_reg, miss_restore_name); | 524 __ JumpIfSmi(value_reg, miss_restore_name); |
| 521 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 525 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| 522 Label do_store, heap_number; | 526 Label do_store, heap_number; |
| 523 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); | 527 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); |
| 524 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow); | 528 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow); |
| 525 | 529 |
| 526 __ JumpIfNotSmi(value_reg, &heap_number); | 530 __ JumpIfNotSmi(value_reg, &heap_number); |
| 527 __ SmiUntag(scratch1, value_reg); | 531 __ SmiUntag(scratch1, value_reg); |
| 528 __ vmov(s0, scratch1); | 532 __ vmov(s0, scratch1); |
| 529 __ vcvt_f64_s32(d0, s0); | 533 __ vcvt_f64_s32(d0, s0); |
| 530 __ jmp(&do_store); | 534 __ jmp(&do_store); |
| 531 | 535 |
| 532 __ bind(&heap_number); | 536 __ bind(&heap_number); |
| 533 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, | 537 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, |
| 534 miss_restore_name, DONT_DO_SMI_CHECK); | 538 miss_restore_name, DONT_DO_SMI_CHECK); |
| 535 __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); | 539 __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); |
| 536 | 540 |
| 537 __ bind(&do_store); | 541 __ bind(&do_store); |
| 538 __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); | 542 __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); |
| 539 } | 543 } |
| 540 | 544 |
| 541 // Stub never generated for non-global objects that require access | 545 // Stub never generated for non-global objects that require access |
| 542 // checks. | 546 // 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 __ push(receiver_reg); | 554 __ push(receiver_reg); |
| 550 __ mov(r2, Operand(transition)); | 555 __ mov(r2, Operand(transition)); |
| 551 __ Push(r2, r0); | 556 __ Push(r2, r0); |
| 552 __ TailCallExternalReference( | 557 __ TailCallExternalReference( |
| 553 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 558 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
| 554 masm->isolate()), | 559 masm->isolate()), |
| 555 3, | 560 3, |
| 556 1); | 561 1); |
| 557 return; | 562 return; |
| 558 } | 563 } |
| 559 | 564 |
| 560 // Update the map of the object. | 565 // Update the map of the object. |
| 561 __ mov(scratch1, Operand(transition)); | 566 __ mov(scratch1, Operand(transition)); |
| 562 __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); | 567 __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
| 563 | 568 |
| 564 // Update the write barrier for the map field and pass the now unused | 569 // Update the write barrier for the map field and pass the now unused |
| 565 // name_reg as scratch register. | 570 // name_reg as scratch register. |
| 566 __ RecordWriteField(receiver_reg, | 571 __ RecordWriteField(receiver_reg, |
| 567 HeapObject::kMapOffset, | 572 HeapObject::kMapOffset, |
| 568 scratch1, | 573 scratch1, |
| 569 scratch2, | 574 scratch2, |
| 570 kLRHasNotBeenSaved, | 575 kLRHasNotBeenSaved, |
| 571 kDontSaveFPRegs, | 576 kDontSaveFPRegs, |
| 572 OMIT_REMEMBERED_SET, | 577 OMIT_REMEMBERED_SET, |
| 573 OMIT_SMI_CHECK); | 578 OMIT_SMI_CHECK); |
| 574 | 579 |
| 580 if (details.type() == CONSTANT_FUNCTION) { |
| 581 ASSERT(value_reg.is(r0)); |
| 582 __ Ret(); |
| 583 return; |
| 584 } |
| 585 |
| 575 int index = transition->instance_descriptors()->GetFieldIndex( | 586 int index = transition->instance_descriptors()->GetFieldIndex( |
| 576 transition->LastAdded()); | 587 transition->LastAdded()); |
| 577 | 588 |
| 578 // Adjust for the number of properties stored in the object. Even in the | 589 // Adjust for the number of properties stored in the object. Even in the |
| 579 // face of a transition we can use the old map here because the size of the | 590 // face of a transition we can use the old map here because the size of the |
| 580 // object and the number of in-object properties is not going to change. | 591 // object and the number of in-object properties is not going to change. |
| 581 index -= object->map()->inobject_properties(); | 592 index -= object->map()->inobject_properties(); |
| 582 | 593 |
| 583 // TODO(verwaest): Share this code as a code stub. | 594 // TODO(verwaest): Share this code as a code stub. |
| 584 SmiCheck smi_check = representation.IsTagged() | 595 SmiCheck smi_check = representation.IsTagged() |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 bool returns_handle = | 962 bool returns_handle = |
| 952 !CallbackTable::ReturnsVoid(masm->isolate(), function_address); | 963 !CallbackTable::ReturnsVoid(masm->isolate(), function_address); |
| 953 ApiFunction fun(function_address); | 964 ApiFunction fun(function_address); |
| 954 ExternalReference::Type type = | 965 ExternalReference::Type type = |
| 955 returns_handle ? | 966 returns_handle ? |
| 956 ExternalReference::DIRECT_API_CALL : | 967 ExternalReference::DIRECT_API_CALL : |
| 957 ExternalReference::DIRECT_API_CALL_NEW; | 968 ExternalReference::DIRECT_API_CALL_NEW; |
| 958 ExternalReference ref = ExternalReference(&fun, | 969 ExternalReference ref = ExternalReference(&fun, |
| 959 type, | 970 type, |
| 960 masm->isolate()); | 971 masm->isolate()); |
| 972 Address thunk_address = returns_handle |
| 973 ? FUNCTION_ADDR(&InvokeInvocationCallback) |
| 974 : FUNCTION_ADDR(&InvokeFunctionCallback); |
| 975 ExternalReference::Type thunk_type = |
| 976 returns_handle ? |
| 977 ExternalReference::PROFILING_API_CALL : |
| 978 ExternalReference::PROFILING_API_CALL_NEW; |
| 979 ApiFunction thunk_fun(thunk_address); |
| 980 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, |
| 981 masm->isolate()); |
| 982 |
| 961 AllowExternalCallThatCantCauseGC scope(masm); | 983 AllowExternalCallThatCantCauseGC scope(masm); |
| 962 __ CallApiFunctionAndReturn(ref, | 984 __ CallApiFunctionAndReturn(ref, |
| 985 function_address, |
| 986 thunk_ref, |
| 987 r1, |
| 963 kStackUnwindSpace, | 988 kStackUnwindSpace, |
| 964 returns_handle, | 989 returns_handle, |
| 965 kFastApiCallArguments + 1); | 990 kFastApiCallArguments + 1); |
| 966 } | 991 } |
| 967 | 992 |
| 968 | 993 |
| 969 class CallInterceptorCompiler BASE_EMBEDDED { | 994 class CallInterceptorCompiler BASE_EMBEDDED { |
| 970 public: | 995 public: |
| 971 CallInterceptorCompiler(StubCompiler* stub_compiler, | 996 CallInterceptorCompiler(StubCompiler* stub_compiler, |
| 972 const ParameterCount& arguments, | 997 const ParameterCount& arguments, |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1449 | 1474 |
| 1450 // Create AccessorInfo instance on the stack above the exit frame with | 1475 // Create AccessorInfo instance on the stack above the exit frame with |
| 1451 // scratch2 (internal::Object** args_) as the data. | 1476 // scratch2 (internal::Object** args_) as the data. |
| 1452 __ str(scratch2(), MemOperand(sp, 1 * kPointerSize)); | 1477 __ str(scratch2(), MemOperand(sp, 1 * kPointerSize)); |
| 1453 __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& | 1478 __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& |
| 1454 | 1479 |
| 1455 const int kStackUnwindSpace = kFastApiCallArguments + 1; | 1480 const int kStackUnwindSpace = kFastApiCallArguments + 1; |
| 1456 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1481 Address getter_address = v8::ToCData<Address>(callback->getter()); |
| 1457 bool returns_handle = | 1482 bool returns_handle = |
| 1458 !CallbackTable::ReturnsVoid(isolate(), getter_address); | 1483 !CallbackTable::ReturnsVoid(isolate(), getter_address); |
| 1484 |
| 1459 ApiFunction fun(getter_address); | 1485 ApiFunction fun(getter_address); |
| 1460 ExternalReference::Type type = | 1486 ExternalReference::Type type = |
| 1461 returns_handle ? | 1487 returns_handle ? |
| 1462 ExternalReference::DIRECT_GETTER_CALL : | 1488 ExternalReference::DIRECT_GETTER_CALL : |
| 1463 ExternalReference::DIRECT_GETTER_CALL_NEW; | 1489 ExternalReference::DIRECT_GETTER_CALL_NEW; |
| 1490 ExternalReference ref = ExternalReference(&fun, type, isolate()); |
| 1464 | 1491 |
| 1465 ExternalReference ref = ExternalReference(&fun, type, isolate()); | 1492 Address thunk_address = returns_handle |
| 1493 ? FUNCTION_ADDR(&InvokeAccessorGetter) |
| 1494 : FUNCTION_ADDR(&InvokeAccessorGetterCallback); |
| 1495 ExternalReference::Type thunk_type = |
| 1496 returns_handle ? |
| 1497 ExternalReference::PROFILING_GETTER_CALL : |
| 1498 ExternalReference::PROFILING_GETTER_CALL_NEW; |
| 1499 ApiFunction thunk_fun(thunk_address); |
| 1500 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, |
| 1501 isolate()); |
| 1466 __ CallApiFunctionAndReturn(ref, | 1502 __ CallApiFunctionAndReturn(ref, |
| 1503 getter_address, |
| 1504 thunk_ref, |
| 1505 r2, |
| 1467 kStackUnwindSpace, | 1506 kStackUnwindSpace, |
| 1468 returns_handle, | 1507 returns_handle, |
| 1469 5); | 1508 5); |
| 1470 } | 1509 } |
| 1471 | 1510 |
| 1472 | 1511 |
| 1473 void BaseLoadStubCompiler::GenerateLoadInterceptor( | 1512 void BaseLoadStubCompiler::GenerateLoadInterceptor( |
| 1474 Register holder_reg, | 1513 Register holder_reg, |
| 1475 Handle<JSObject> object, | 1514 Handle<JSObject> object, |
| 1476 Handle<JSObject> interceptor_holder, | 1515 Handle<JSObject> interceptor_holder, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 // Get the receiver from the stack. | 1618 // Get the receiver from the stack. |
| 1580 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 1619 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 1581 | 1620 |
| 1582 // Check that the maps haven't changed. | 1621 // Check that the maps haven't changed. |
| 1583 __ JumpIfSmi(r0, miss); | 1622 __ JumpIfSmi(r0, miss); |
| 1584 CheckPrototypes(object, r0, holder, r3, r1, r4, name, miss); | 1623 CheckPrototypes(object, r0, holder, r3, r1, r4, name, miss); |
| 1585 } | 1624 } |
| 1586 | 1625 |
| 1587 | 1626 |
| 1588 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1627 void CallStubCompiler::GenerateLoadFunctionFromCell( |
| 1589 Handle<JSGlobalPropertyCell> cell, | 1628 Handle<Cell> cell, |
| 1590 Handle<JSFunction> function, | 1629 Handle<JSFunction> function, |
| 1591 Label* miss) { | 1630 Label* miss) { |
| 1592 // Get the value from the cell. | 1631 // Get the value from the cell. |
| 1593 __ mov(r3, Operand(cell)); | 1632 __ mov(r3, Operand(cell)); |
| 1594 __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 1633 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); |
| 1595 | 1634 |
| 1596 // Check that the cell contains the same function. | 1635 // Check that the cell contains the same function. |
| 1597 if (heap()->InNewSpace(*function)) { | 1636 if (heap()->InNewSpace(*function)) { |
| 1598 // We can't embed a pointer to a function in new space so we have | 1637 // We can't embed a pointer to a function in new space so we have |
| 1599 // to verify that the shared function info is unchanged. This has | 1638 // to verify that the shared function info is unchanged. This has |
| 1600 // the nice side effect that multiple closures based on the same | 1639 // the nice side effect that multiple closures based on the same |
| 1601 // function can all use this call IC. Before we load through the | 1640 // function can all use this call IC. Before we load through the |
| 1602 // function, we have to verify that it still is a function. | 1641 // function, we have to verify that it still is a function. |
| 1603 __ JumpIfSmi(r1, miss); | 1642 __ JumpIfSmi(r1, miss); |
| 1604 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); | 1643 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1652 | 1691 |
| 1653 // Handle call cache miss. | 1692 // Handle call cache miss. |
| 1654 __ bind(&miss); | 1693 __ bind(&miss); |
| 1655 GenerateMissBranch(); | 1694 GenerateMissBranch(); |
| 1656 | 1695 |
| 1657 // Return the generated code. | 1696 // Return the generated code. |
| 1658 return GetCode(Code::FIELD, name); | 1697 return GetCode(Code::FIELD, name); |
| 1659 } | 1698 } |
| 1660 | 1699 |
| 1661 | 1700 |
| 1701 Handle<Code> CallStubCompiler::CompileArrayCodeCall( |
| 1702 Handle<Object> object, |
| 1703 Handle<JSObject> holder, |
| 1704 Handle<Cell> cell, |
| 1705 Handle<JSFunction> function, |
| 1706 Handle<String> name, |
| 1707 Code::StubType type) { |
| 1708 Label miss; |
| 1709 |
| 1710 // Check that function is still array |
| 1711 const int argc = arguments().immediate(); |
| 1712 GenerateNameCheck(name, &miss); |
| 1713 Register receiver = r1; |
| 1714 |
| 1715 if (cell.is_null()) { |
| 1716 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1717 |
| 1718 // Check that the receiver isn't a smi. |
| 1719 __ JumpIfSmi(receiver, &miss); |
| 1720 |
| 1721 // Check that the maps haven't changed. |
| 1722 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, r3, r0, |
| 1723 r4, name, &miss); |
| 1724 } else { |
| 1725 ASSERT(cell->value() == *function); |
| 1726 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 1727 &miss); |
| 1728 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1729 } |
| 1730 |
| 1731 Handle<Smi> kind(Smi::FromInt(GetInitialFastElementsKind()), isolate()); |
| 1732 Handle<Cell> kind_feedback_cell = |
| 1733 isolate()->factory()->NewCell(kind); |
| 1734 __ mov(r0, Operand(argc)); |
| 1735 __ mov(r2, Operand(kind_feedback_cell)); |
| 1736 __ mov(r1, Operand(function)); |
| 1737 |
| 1738 ArrayConstructorStub stub(isolate()); |
| 1739 __ TailCallStub(&stub); |
| 1740 |
| 1741 __ bind(&miss); |
| 1742 GenerateMissBranch(); |
| 1743 |
| 1744 // Return the generated code. |
| 1745 return GetCode(type, name); |
| 1746 } |
| 1747 |
| 1748 |
| 1662 Handle<Code> CallStubCompiler::CompileArrayPushCall( | 1749 Handle<Code> CallStubCompiler::CompileArrayPushCall( |
| 1663 Handle<Object> object, | 1750 Handle<Object> object, |
| 1664 Handle<JSObject> holder, | 1751 Handle<JSObject> holder, |
| 1665 Handle<JSGlobalPropertyCell> cell, | 1752 Handle<Cell> cell, |
| 1666 Handle<JSFunction> function, | 1753 Handle<JSFunction> function, |
| 1667 Handle<String> name) { | 1754 Handle<String> name, |
| 1755 Code::StubType type) { |
| 1668 // ----------- S t a t e ------------- | 1756 // ----------- S t a t e ------------- |
| 1669 // -- r2 : name | 1757 // -- r2 : name |
| 1670 // -- lr : return address | 1758 // -- lr : return address |
| 1671 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1759 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 1672 // -- ... | 1760 // -- ... |
| 1673 // -- sp[argc * 4] : receiver | 1761 // -- sp[argc * 4] : receiver |
| 1674 // ----------------------------------- | 1762 // ----------------------------------- |
| 1675 | 1763 |
| 1676 // If object is not an array, bail out to regular call. | 1764 // If object is not an array, bail out to regular call. |
| 1677 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); | 1765 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 __ bind(&call_builtin); | 1989 __ bind(&call_builtin); |
| 1902 __ TailCallExternalReference( | 1990 __ TailCallExternalReference( |
| 1903 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); | 1991 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); |
| 1904 } | 1992 } |
| 1905 | 1993 |
| 1906 // Handle call cache miss. | 1994 // Handle call cache miss. |
| 1907 __ bind(&miss); | 1995 __ bind(&miss); |
| 1908 GenerateMissBranch(); | 1996 GenerateMissBranch(); |
| 1909 | 1997 |
| 1910 // Return the generated code. | 1998 // Return the generated code. |
| 1911 return GetCode(function); | 1999 return GetCode(type, name); |
| 1912 } | 2000 } |
| 1913 | 2001 |
| 1914 | 2002 |
| 1915 Handle<Code> CallStubCompiler::CompileArrayPopCall( | 2003 Handle<Code> CallStubCompiler::CompileArrayPopCall( |
| 1916 Handle<Object> object, | 2004 Handle<Object> object, |
| 1917 Handle<JSObject> holder, | 2005 Handle<JSObject> holder, |
| 1918 Handle<JSGlobalPropertyCell> cell, | 2006 Handle<Cell> cell, |
| 1919 Handle<JSFunction> function, | 2007 Handle<JSFunction> function, |
| 1920 Handle<String> name) { | 2008 Handle<String> name, |
| 2009 Code::StubType type) { |
| 1921 // ----------- S t a t e ------------- | 2010 // ----------- S t a t e ------------- |
| 1922 // -- r2 : name | 2011 // -- r2 : name |
| 1923 // -- lr : return address | 2012 // -- lr : return address |
| 1924 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2013 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 1925 // -- ... | 2014 // -- ... |
| 1926 // -- sp[argc * 4] : receiver | 2015 // -- sp[argc * 4] : receiver |
| 1927 // ----------------------------------- | 2016 // ----------------------------------- |
| 1928 | 2017 |
| 1929 // If object is not an array, bail out to regular call. | 2018 // If object is not an array, bail out to regular call. |
| 1930 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); | 2019 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1983 | 2072 |
| 1984 __ bind(&call_builtin); | 2073 __ bind(&call_builtin); |
| 1985 __ TailCallExternalReference( | 2074 __ TailCallExternalReference( |
| 1986 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); | 2075 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); |
| 1987 | 2076 |
| 1988 // Handle call cache miss. | 2077 // Handle call cache miss. |
| 1989 __ bind(&miss); | 2078 __ bind(&miss); |
| 1990 GenerateMissBranch(); | 2079 GenerateMissBranch(); |
| 1991 | 2080 |
| 1992 // Return the generated code. | 2081 // Return the generated code. |
| 1993 return GetCode(function); | 2082 return GetCode(type, name); |
| 1994 } | 2083 } |
| 1995 | 2084 |
| 1996 | 2085 |
| 1997 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( | 2086 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( |
| 1998 Handle<Object> object, | 2087 Handle<Object> object, |
| 1999 Handle<JSObject> holder, | 2088 Handle<JSObject> holder, |
| 2000 Handle<JSGlobalPropertyCell> cell, | 2089 Handle<Cell> cell, |
| 2001 Handle<JSFunction> function, | 2090 Handle<JSFunction> function, |
| 2002 Handle<String> name) { | 2091 Handle<String> name, |
| 2092 Code::StubType type) { |
| 2003 // ----------- S t a t e ------------- | 2093 // ----------- S t a t e ------------- |
| 2004 // -- r2 : function name | 2094 // -- r2 : function name |
| 2005 // -- lr : return address | 2095 // -- lr : return address |
| 2006 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2096 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 2007 // -- ... | 2097 // -- ... |
| 2008 // -- sp[argc * 4] : receiver | 2098 // -- sp[argc * 4] : receiver |
| 2009 // ----------------------------------- | 2099 // ----------------------------------- |
| 2010 | 2100 |
| 2011 // If object is not a string, bail out to regular call. | 2101 // If object is not a string, bail out to regular call. |
| 2012 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); | 2102 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2065 __ Ret(); | 2155 __ Ret(); |
| 2066 } | 2156 } |
| 2067 | 2157 |
| 2068 __ bind(&miss); | 2158 __ bind(&miss); |
| 2069 // Restore function name in r2. | 2159 // Restore function name in r2. |
| 2070 __ Move(r2, name); | 2160 __ Move(r2, name); |
| 2071 __ bind(&name_miss); | 2161 __ bind(&name_miss); |
| 2072 GenerateMissBranch(); | 2162 GenerateMissBranch(); |
| 2073 | 2163 |
| 2074 // Return the generated code. | 2164 // Return the generated code. |
| 2075 return GetCode(function); | 2165 return GetCode(type, name); |
| 2076 } | 2166 } |
| 2077 | 2167 |
| 2078 | 2168 |
| 2079 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 2169 Handle<Code> CallStubCompiler::CompileStringCharAtCall( |
| 2080 Handle<Object> object, | 2170 Handle<Object> object, |
| 2081 Handle<JSObject> holder, | 2171 Handle<JSObject> holder, |
| 2082 Handle<JSGlobalPropertyCell> cell, | 2172 Handle<Cell> cell, |
| 2083 Handle<JSFunction> function, | 2173 Handle<JSFunction> function, |
| 2084 Handle<String> name) { | 2174 Handle<String> name, |
| 2175 Code::StubType type) { |
| 2085 // ----------- S t a t e ------------- | 2176 // ----------- S t a t e ------------- |
| 2086 // -- r2 : function name | 2177 // -- r2 : function name |
| 2087 // -- lr : return address | 2178 // -- lr : return address |
| 2088 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2179 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 2089 // -- ... | 2180 // -- ... |
| 2090 // -- sp[argc * 4] : receiver | 2181 // -- sp[argc * 4] : receiver |
| 2091 // ----------------------------------- | 2182 // ----------------------------------- |
| 2092 | 2183 |
| 2093 // If object is not a string, bail out to regular call. | 2184 // If object is not a string, bail out to regular call. |
| 2094 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); | 2185 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2148 __ Ret(); | 2239 __ Ret(); |
| 2149 } | 2240 } |
| 2150 | 2241 |
| 2151 __ bind(&miss); | 2242 __ bind(&miss); |
| 2152 // Restore function name in r2. | 2243 // Restore function name in r2. |
| 2153 __ Move(r2, name); | 2244 __ Move(r2, name); |
| 2154 __ bind(&name_miss); | 2245 __ bind(&name_miss); |
| 2155 GenerateMissBranch(); | 2246 GenerateMissBranch(); |
| 2156 | 2247 |
| 2157 // Return the generated code. | 2248 // Return the generated code. |
| 2158 return GetCode(function); | 2249 return GetCode(type, name); |
| 2159 } | 2250 } |
| 2160 | 2251 |
| 2161 | 2252 |
| 2162 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 2253 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( |
| 2163 Handle<Object> object, | 2254 Handle<Object> object, |
| 2164 Handle<JSObject> holder, | 2255 Handle<JSObject> holder, |
| 2165 Handle<JSGlobalPropertyCell> cell, | 2256 Handle<Cell> cell, |
| 2166 Handle<JSFunction> function, | 2257 Handle<JSFunction> function, |
| 2167 Handle<String> name) { | 2258 Handle<String> name, |
| 2259 Code::StubType type) { |
| 2168 // ----------- S t a t e ------------- | 2260 // ----------- S t a t e ------------- |
| 2169 // -- r2 : function name | 2261 // -- r2 : function name |
| 2170 // -- lr : return address | 2262 // -- lr : return address |
| 2171 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2263 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 2172 // -- ... | 2264 // -- ... |
| 2173 // -- sp[argc * 4] : receiver | 2265 // -- sp[argc * 4] : receiver |
| 2174 // ----------------------------------- | 2266 // ----------------------------------- |
| 2175 | 2267 |
| 2176 const int argc = arguments().immediate(); | 2268 const int argc = arguments().immediate(); |
| 2177 | 2269 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2220 __ bind(&slow); | 2312 __ bind(&slow); |
| 2221 ParameterCount expected(function); | 2313 ParameterCount expected(function); |
| 2222 __ InvokeFunction(function, expected, arguments(), | 2314 __ InvokeFunction(function, expected, arguments(), |
| 2223 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2315 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2224 | 2316 |
| 2225 __ bind(&miss); | 2317 __ bind(&miss); |
| 2226 // r2: function name. | 2318 // r2: function name. |
| 2227 GenerateMissBranch(); | 2319 GenerateMissBranch(); |
| 2228 | 2320 |
| 2229 // Return the generated code. | 2321 // Return the generated code. |
| 2230 return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); | 2322 return GetCode(type, name); |
| 2231 } | 2323 } |
| 2232 | 2324 |
| 2233 | 2325 |
| 2234 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 2326 Handle<Code> CallStubCompiler::CompileMathFloorCall( |
| 2235 Handle<Object> object, | 2327 Handle<Object> object, |
| 2236 Handle<JSObject> holder, | 2328 Handle<JSObject> holder, |
| 2237 Handle<JSGlobalPropertyCell> cell, | 2329 Handle<Cell> cell, |
| 2238 Handle<JSFunction> function, | 2330 Handle<JSFunction> function, |
| 2239 Handle<String> name) { | 2331 Handle<String> name, |
| 2332 Code::StubType type) { |
| 2240 // ----------- S t a t e ------------- | 2333 // ----------- S t a t e ------------- |
| 2241 // -- r2 : function name | 2334 // -- r2 : function name |
| 2242 // -- lr : return address | 2335 // -- lr : return address |
| 2243 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2336 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 2244 // -- ... | 2337 // -- ... |
| 2245 // -- sp[argc * 4] : receiver | 2338 // -- sp[argc * 4] : receiver |
| 2246 // ----------------------------------- | 2339 // ----------------------------------- |
| 2247 | 2340 |
| 2248 const int argc = arguments().immediate(); | 2341 const int argc = arguments().immediate(); |
| 2249 // If the object is not a JSObject or we got an unexpected number of | 2342 // If the object is not a JSObject or we got an unexpected number of |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2328 // because the function makes no use of it. | 2421 // because the function makes no use of it. |
| 2329 ParameterCount expected(function); | 2422 ParameterCount expected(function); |
| 2330 __ InvokeFunction(function, expected, arguments(), | 2423 __ InvokeFunction(function, expected, arguments(), |
| 2331 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2424 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2332 | 2425 |
| 2333 __ bind(&miss); | 2426 __ bind(&miss); |
| 2334 // r2: function name. | 2427 // r2: function name. |
| 2335 GenerateMissBranch(); | 2428 GenerateMissBranch(); |
| 2336 | 2429 |
| 2337 // Return the generated code. | 2430 // Return the generated code. |
| 2338 return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); | 2431 return GetCode(type, name); |
| 2339 } | 2432 } |
| 2340 | 2433 |
| 2341 | 2434 |
| 2342 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 2435 Handle<Code> CallStubCompiler::CompileMathAbsCall( |
| 2343 Handle<Object> object, | 2436 Handle<Object> object, |
| 2344 Handle<JSObject> holder, | 2437 Handle<JSObject> holder, |
| 2345 Handle<JSGlobalPropertyCell> cell, | 2438 Handle<Cell> cell, |
| 2346 Handle<JSFunction> function, | 2439 Handle<JSFunction> function, |
| 2347 Handle<String> name) { | 2440 Handle<String> name, |
| 2441 Code::StubType type) { |
| 2348 // ----------- S t a t e ------------- | 2442 // ----------- S t a t e ------------- |
| 2349 // -- r2 : function name | 2443 // -- r2 : function name |
| 2350 // -- lr : return address | 2444 // -- lr : return address |
| 2351 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2445 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 2352 // -- ... | 2446 // -- ... |
| 2353 // -- sp[argc * 4] : receiver | 2447 // -- sp[argc * 4] : receiver |
| 2354 // ----------------------------------- | 2448 // ----------------------------------- |
| 2355 | 2449 |
| 2356 const int argc = arguments().immediate(); | 2450 const int argc = arguments().immediate(); |
| 2357 // If the object is not a JSObject or we got an unexpected number of | 2451 // If the object is not a JSObject or we got an unexpected number of |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2426 __ bind(&slow); | 2520 __ bind(&slow); |
| 2427 ParameterCount expected(function); | 2521 ParameterCount expected(function); |
| 2428 __ InvokeFunction(function, expected, arguments(), | 2522 __ InvokeFunction(function, expected, arguments(), |
| 2429 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2523 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2430 | 2524 |
| 2431 __ bind(&miss); | 2525 __ bind(&miss); |
| 2432 // r2: function name. | 2526 // r2: function name. |
| 2433 GenerateMissBranch(); | 2527 GenerateMissBranch(); |
| 2434 | 2528 |
| 2435 // Return the generated code. | 2529 // Return the generated code. |
| 2436 return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); | 2530 return GetCode(type, name); |
| 2437 } | 2531 } |
| 2438 | 2532 |
| 2439 | 2533 |
| 2440 Handle<Code> CallStubCompiler::CompileFastApiCall( | 2534 Handle<Code> CallStubCompiler::CompileFastApiCall( |
| 2441 const CallOptimization& optimization, | 2535 const CallOptimization& optimization, |
| 2442 Handle<Object> object, | 2536 Handle<Object> object, |
| 2443 Handle<JSObject> holder, | 2537 Handle<JSObject> holder, |
| 2444 Handle<JSGlobalPropertyCell> cell, | 2538 Handle<Cell> cell, |
| 2445 Handle<JSFunction> function, | 2539 Handle<JSFunction> function, |
| 2446 Handle<String> name) { | 2540 Handle<String> name) { |
| 2447 Counters* counters = isolate()->counters(); | 2541 Counters* counters = isolate()->counters(); |
| 2448 | 2542 |
| 2449 ASSERT(optimization.is_simple_api_call()); | 2543 ASSERT(optimization.is_simple_api_call()); |
| 2450 // Bail out if object is a global object as we don't want to | 2544 // Bail out if object is a global object as we don't want to |
| 2451 // repatch it to global receiver. | 2545 // repatch it to global receiver. |
| 2452 if (object->IsGlobalObject()) return Handle<Code>::null(); | 2546 if (object->IsGlobalObject()) return Handle<Code>::null(); |
| 2453 if (!cell.is_null()) return Handle<Code>::null(); | 2547 if (!cell.is_null()) return Handle<Code>::null(); |
| 2454 if (!object->IsJSObject()) return Handle<Code>::null(); | 2548 if (!object->IsJSObject()) return Handle<Code>::null(); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2606 | 2700 |
| 2607 | 2701 |
| 2608 Handle<Code> CallStubCompiler::CompileCallConstant( | 2702 Handle<Code> CallStubCompiler::CompileCallConstant( |
| 2609 Handle<Object> object, | 2703 Handle<Object> object, |
| 2610 Handle<JSObject> holder, | 2704 Handle<JSObject> holder, |
| 2611 Handle<Name> name, | 2705 Handle<Name> name, |
| 2612 CheckType check, | 2706 CheckType check, |
| 2613 Handle<JSFunction> function) { | 2707 Handle<JSFunction> function) { |
| 2614 if (HasCustomCallGenerator(function)) { | 2708 if (HasCustomCallGenerator(function)) { |
| 2615 Handle<Code> code = CompileCustomCall(object, holder, | 2709 Handle<Code> code = CompileCustomCall(object, holder, |
| 2616 Handle<JSGlobalPropertyCell>::null(), | 2710 Handle<Cell>::null(), |
| 2617 function, Handle<String>::cast(name)); | 2711 function, Handle<String>::cast(name), |
| 2712 Code::CONSTANT_FUNCTION); |
| 2618 // A null handle means bail out to the regular compiler code below. | 2713 // A null handle means bail out to the regular compiler code below. |
| 2619 if (!code.is_null()) return code; | 2714 if (!code.is_null()) return code; |
| 2620 } | 2715 } |
| 2621 | 2716 |
| 2622 Label success; | 2717 Label success; |
| 2623 | 2718 |
| 2624 CompileHandlerFrontend(object, holder, name, check, &success); | 2719 CompileHandlerFrontend(object, holder, name, check, &success); |
| 2625 __ bind(&success); | 2720 __ bind(&success); |
| 2626 CompileHandlerBackend(function); | 2721 CompileHandlerBackend(function); |
| 2627 | 2722 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2664 GenerateMissBranch(); | 2759 GenerateMissBranch(); |
| 2665 | 2760 |
| 2666 // Return the generated code. | 2761 // Return the generated code. |
| 2667 return GetCode(Code::INTERCEPTOR, name); | 2762 return GetCode(Code::INTERCEPTOR, name); |
| 2668 } | 2763 } |
| 2669 | 2764 |
| 2670 | 2765 |
| 2671 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2766 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2672 Handle<JSObject> object, | 2767 Handle<JSObject> object, |
| 2673 Handle<GlobalObject> holder, | 2768 Handle<GlobalObject> holder, |
| 2674 Handle<JSGlobalPropertyCell> cell, | 2769 Handle<PropertyCell> cell, |
| 2675 Handle<JSFunction> function, | 2770 Handle<JSFunction> function, |
| 2676 Handle<Name> name) { | 2771 Handle<Name> name) { |
| 2677 // ----------- S t a t e ------------- | 2772 // ----------- S t a t e ------------- |
| 2678 // -- r2 : name | 2773 // -- r2 : name |
| 2679 // -- lr : return address | 2774 // -- lr : return address |
| 2680 // ----------------------------------- | 2775 // ----------------------------------- |
| 2681 if (HasCustomCallGenerator(function)) { | 2776 if (HasCustomCallGenerator(function)) { |
| 2682 Handle<Code> code = CompileCustomCall( | 2777 Handle<Code> code = CompileCustomCall( |
| 2683 object, holder, cell, function, Handle<String>::cast(name)); | 2778 object, holder, cell, function, Handle<String>::cast(name), |
| 2779 Code::NORMAL); |
| 2684 // A null handle means bail out to the regular compiler code below. | 2780 // A null handle means bail out to the regular compiler code below. |
| 2685 if (!code.is_null()) return code; | 2781 if (!code.is_null()) return code; |
| 2686 } | 2782 } |
| 2687 | 2783 |
| 2688 Label miss; | 2784 Label miss; |
| 2689 GenerateNameCheck(name, &miss); | 2785 GenerateNameCheck(name, &miss); |
| 2690 | 2786 |
| 2691 // Get the number of arguments. | 2787 // Get the number of arguments. |
| 2692 const int argc = arguments().immediate(); | 2788 const int argc = arguments().immediate(); |
| 2693 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2789 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2837 __ bind(&miss); | 2933 __ bind(&miss); |
| 2838 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2934 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2839 | 2935 |
| 2840 // Return the generated code. | 2936 // Return the generated code. |
| 2841 return GetICCode(kind(), Code::INTERCEPTOR, name); | 2937 return GetICCode(kind(), Code::INTERCEPTOR, name); |
| 2842 } | 2938 } |
| 2843 | 2939 |
| 2844 | 2940 |
| 2845 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 2941 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
| 2846 Handle<GlobalObject> object, | 2942 Handle<GlobalObject> object, |
| 2847 Handle<JSGlobalPropertyCell> cell, | 2943 Handle<PropertyCell> cell, |
| 2848 Handle<Name> name) { | 2944 Handle<Name> name) { |
| 2849 Label miss; | 2945 Label miss; |
| 2850 | 2946 |
| 2851 // Check that the map of the global has not changed. | 2947 // Check that the map of the global has not changed. |
| 2852 __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); | 2948 __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); |
| 2853 __ cmp(scratch1(), Operand(Handle<Map>(object->map()))); | 2949 __ cmp(scratch1(), Operand(Handle<Map>(object->map()))); |
| 2854 __ b(ne, &miss); | 2950 __ b(ne, &miss); |
| 2855 | 2951 |
| 2856 // Check that the value in the cell is not the hole. If it is, this | 2952 // Check that the value in the cell is not the hole. If it is, this |
| 2857 // cell could have been deleted and reintroducing the global needs | 2953 // cell could have been deleted and reintroducing the global needs |
| 2858 // to update the property details in the property dictionary of the | 2954 // to update the property details in the property dictionary of the |
| 2859 // global object. We bail out to the runtime system to do that. | 2955 // global object. We bail out to the runtime system to do that. |
| 2860 __ mov(scratch1(), Operand(cell)); | 2956 __ mov(scratch1(), Operand(cell)); |
| 2861 __ LoadRoot(scratch2(), Heap::kTheHoleValueRootIndex); | 2957 __ LoadRoot(scratch2(), Heap::kTheHoleValueRootIndex); |
| 2862 __ ldr(scratch3(), | 2958 __ ldr(scratch3(), FieldMemOperand(scratch1(), Cell::kValueOffset)); |
| 2863 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); | |
| 2864 __ cmp(scratch3(), scratch2()); | 2959 __ cmp(scratch3(), scratch2()); |
| 2865 __ b(eq, &miss); | 2960 __ b(eq, &miss); |
| 2866 | 2961 |
| 2867 // Store the value in the cell. | 2962 // Store the value in the cell. |
| 2868 __ str(value(), | 2963 __ str(value(), FieldMemOperand(scratch1(), Cell::kValueOffset)); |
| 2869 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); | |
| 2870 // Cells are always rescanned, so no write barrier here. | 2964 // Cells are always rescanned, so no write barrier here. |
| 2871 | 2965 |
| 2872 Counters* counters = isolate()->counters(); | 2966 Counters* counters = isolate()->counters(); |
| 2873 __ IncrementCounter( | 2967 __ IncrementCounter( |
| 2874 counters->named_store_global_inline(), 1, scratch1(), scratch2()); | 2968 counters->named_store_global_inline(), 1, scratch1(), scratch2()); |
| 2875 __ Ret(); | 2969 __ Ret(); |
| 2876 | 2970 |
| 2877 // Handle store cache miss. | 2971 // Handle store cache miss. |
| 2878 __ bind(&miss); | 2972 __ bind(&miss); |
| 2879 __ IncrementCounter( | 2973 __ IncrementCounter( |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2983 } | 3077 } |
| 2984 | 3078 |
| 2985 | 3079 |
| 2986 #undef __ | 3080 #undef __ |
| 2987 #define __ ACCESS_MASM(masm()) | 3081 #define __ ACCESS_MASM(masm()) |
| 2988 | 3082 |
| 2989 | 3083 |
| 2990 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 3084 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
| 2991 Handle<JSObject> object, | 3085 Handle<JSObject> object, |
| 2992 Handle<GlobalObject> global, | 3086 Handle<GlobalObject> global, |
| 2993 Handle<JSGlobalPropertyCell> cell, | 3087 Handle<PropertyCell> cell, |
| 2994 Handle<Name> name, | 3088 Handle<Name> name, |
| 2995 bool is_dont_delete) { | 3089 bool is_dont_delete) { |
| 2996 Label success, miss; | 3090 Label success, miss; |
| 2997 | 3091 |
| 2998 __ CheckMap( | 3092 __ CheckMap( |
| 2999 receiver(), scratch1(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK); | 3093 receiver(), scratch1(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK); |
| 3000 HandlerFrontendHeader( | 3094 HandlerFrontendHeader( |
| 3001 object, receiver(), Handle<JSObject>::cast(global), name, &miss); | 3095 object, receiver(), Handle<JSObject>::cast(global), name, &miss); |
| 3002 | 3096 |
| 3003 // Get the value from the cell. | 3097 // Get the value from the cell. |
| 3004 __ mov(r3, Operand(cell)); | 3098 __ mov(r3, Operand(cell)); |
| 3005 __ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 3099 __ ldr(r4, FieldMemOperand(r3, Cell::kValueOffset)); |
| 3006 | 3100 |
| 3007 // Check for deleted property if property can actually be deleted. | 3101 // Check for deleted property if property can actually be deleted. |
| 3008 if (!is_dont_delete) { | 3102 if (!is_dont_delete) { |
| 3009 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 3103 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 3010 __ cmp(r4, ip); | 3104 __ cmp(r4, ip); |
| 3011 __ b(eq, &miss); | 3105 __ b(eq, &miss); |
| 3012 } | 3106 } |
| 3013 | 3107 |
| 3014 HandlerFrontendFooter(&success, &miss); | 3108 HandlerFrontendFooter(&success, &miss); |
| 3015 __ bind(&success); | 3109 __ bind(&success); |
| (...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3641 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3735 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
| 3642 } | 3736 } |
| 3643 } | 3737 } |
| 3644 | 3738 |
| 3645 | 3739 |
| 3646 #undef __ | 3740 #undef __ |
| 3647 | 3741 |
| 3648 } } // namespace v8::internal | 3742 } } // namespace v8::internal |
| 3649 | 3743 |
| 3650 #endif // V8_TARGET_ARCH_ARM | 3744 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |