| 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 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 Immediate(reinterpret_cast<int>(masm->isolate()))); | 496 Immediate(reinterpret_cast<int>(masm->isolate()))); |
| 497 __ mov(Operand(esp, 5 * kPointerSize), | 497 __ mov(Operand(esp, 5 * kPointerSize), |
| 498 masm->isolate()->factory()->undefined_value()); | 498 masm->isolate()->factory()->undefined_value()); |
| 499 __ mov(Operand(esp, 6 * kPointerSize), | 499 __ mov(Operand(esp, 6 * kPointerSize), |
| 500 masm->isolate()->factory()->undefined_value()); | 500 masm->isolate()->factory()->undefined_value()); |
| 501 | 501 |
| 502 // Prepare arguments. | 502 // Prepare arguments. |
| 503 STATIC_ASSERT(kFastApiCallArguments == 6); | 503 STATIC_ASSERT(kFastApiCallArguments == 6); |
| 504 __ lea(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); | 504 __ lea(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); |
| 505 | 505 |
| 506 const int kApiArgc = 1; // API function gets reference to the v8::Arguments. | 506 |
| 507 // API function gets reference to the v8::Arguments. If CPU profiler |
| 508 // is enabled wrapper function will be called and we need to pass |
| 509 // address of the callback as additional parameter, always allocate |
| 510 // space for it. |
| 511 const int kApiArgc = 1 + 1; |
| 507 | 512 |
| 508 // Allocate the v8::Arguments structure in the arguments' space since | 513 // Allocate the v8::Arguments structure in the arguments' space since |
| 509 // it's not controlled by GC. | 514 // it's not controlled by GC. |
| 510 const int kApiStackSpace = 4; | 515 const int kApiStackSpace = 4; |
| 511 | 516 |
| 512 // Function address is a foreign pointer outside V8's heap. | 517 // Function address is a foreign pointer outside V8's heap. |
| 513 Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 518 Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
| 514 bool returns_handle = | 519 bool returns_handle = |
| 515 !CallbackTable::ReturnsVoid(masm->isolate(), | 520 !CallbackTable::ReturnsVoid(masm->isolate(), |
| 516 reinterpret_cast<void*>(function_address)); | 521 reinterpret_cast<void*>(function_address)); |
| 517 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace, returns_handle); | 522 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace, returns_handle); |
| 518 | 523 |
| 519 // v8::Arguments::implicit_args_. | 524 // v8::Arguments::implicit_args_. |
| 520 __ mov(ApiParameterOperand(1, returns_handle), eax); | 525 __ mov(ApiParameterOperand(2, returns_handle), eax); |
| 521 __ add(eax, Immediate(argc * kPointerSize)); | 526 __ add(eax, Immediate(argc * kPointerSize)); |
| 522 // v8::Arguments::values_. | 527 // v8::Arguments::values_. |
| 523 __ mov(ApiParameterOperand(2, returns_handle), eax); | 528 __ mov(ApiParameterOperand(3, returns_handle), eax); |
| 524 // v8::Arguments::length_. | 529 // v8::Arguments::length_. |
| 525 __ Set(ApiParameterOperand(3, returns_handle), Immediate(argc)); | 530 __ Set(ApiParameterOperand(4, returns_handle), Immediate(argc)); |
| 526 // v8::Arguments::is_construct_call_. | 531 // v8::Arguments::is_construct_call_. |
| 527 __ Set(ApiParameterOperand(4, returns_handle), Immediate(0)); | 532 __ Set(ApiParameterOperand(5, returns_handle), Immediate(0)); |
| 528 | 533 |
| 529 // v8::InvocationCallback's argument. | 534 // v8::InvocationCallback's argument. |
| 530 __ lea(eax, ApiParameterOperand(1, returns_handle)); | 535 __ lea(eax, ApiParameterOperand(2, returns_handle)); |
| 531 __ mov(ApiParameterOperand(0, returns_handle), eax); | 536 __ mov(ApiParameterOperand(0, returns_handle), eax); |
| 532 | 537 |
| 538 Address thunk_address = returns_handle |
| 539 ? FUNCTION_ADDR(&InvokeInvocationCallback) |
| 540 : FUNCTION_ADDR(&InvokeFunctionCallback); |
| 541 |
| 533 __ CallApiFunctionAndReturn(function_address, | 542 __ CallApiFunctionAndReturn(function_address, |
| 543 thunk_address, |
| 544 ApiParameterOperand(1, returns_handle), |
| 534 argc + kFastApiCallArguments + 1, | 545 argc + kFastApiCallArguments + 1, |
| 535 returns_handle, | 546 returns_handle, |
| 536 kFastApiCallArguments + 1); | 547 kFastApiCallArguments + 1); |
| 537 } | 548 } |
| 538 | 549 |
| 539 | 550 |
| 540 class CallInterceptorCompiler BASE_EMBEDDED { | 551 class CallInterceptorCompiler BASE_EMBEDDED { |
| 541 public: | 552 public: |
| 542 CallInterceptorCompiler(StubCompiler* stub_compiler, | 553 CallInterceptorCompiler(StubCompiler* stub_compiler, |
| 543 const ParameterCount& arguments, | 554 const ParameterCount& arguments, |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 | 757 |
| 747 | 758 |
| 748 // Generate code to check that a global property cell is empty. Create | 759 // Generate code to check that a global property cell is empty. Create |
| 749 // the property cell at compilation time if no cell exists for the | 760 // the property cell at compilation time if no cell exists for the |
| 750 // property. | 761 // property. |
| 751 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 762 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 752 Handle<GlobalObject> global, | 763 Handle<GlobalObject> global, |
| 753 Handle<Name> name, | 764 Handle<Name> name, |
| 754 Register scratch, | 765 Register scratch, |
| 755 Label* miss) { | 766 Label* miss) { |
| 756 Handle<JSGlobalPropertyCell> cell = | 767 Handle<PropertyCell> cell = |
| 757 GlobalObject::EnsurePropertyCell(global, name); | 768 GlobalObject::EnsurePropertyCell(global, name); |
| 758 ASSERT(cell->value()->IsTheHole()); | 769 ASSERT(cell->value()->IsTheHole()); |
| 759 Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value(); | 770 Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value(); |
| 760 if (Serializer::enabled()) { | 771 if (Serializer::enabled()) { |
| 761 __ mov(scratch, Immediate(cell)); | 772 __ mov(scratch, Immediate(cell)); |
| 762 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 773 __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset), |
| 763 Immediate(the_hole)); | 774 Immediate(the_hole)); |
| 764 } else { | 775 } else { |
| 765 __ cmp(Operand::Cell(cell), Immediate(the_hole)); | 776 __ cmp(Operand::ForCell(cell), Immediate(the_hole)); |
| 766 } | 777 } |
| 767 __ j(not_equal, miss); | 778 __ j(not_equal, miss); |
| 768 } | 779 } |
| 769 | 780 |
| 770 | 781 |
| 771 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 782 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
| 772 // but may be destroyed if store is successful. | 783 // but may be destroyed if store is successful. |
| 773 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, | 784 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| 774 Handle<JSObject> object, | 785 Handle<JSObject> object, |
| 775 LookupResult* lookup, | 786 LookupResult* lookup, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 miss_restore_name); | 843 miss_restore_name); |
| 833 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { | 844 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { |
| 834 GenerateDictionaryNegativeLookup( | 845 GenerateDictionaryNegativeLookup( |
| 835 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); | 846 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); |
| 836 } | 847 } |
| 837 } | 848 } |
| 838 } | 849 } |
| 839 | 850 |
| 840 Register storage_reg = name_reg; | 851 Register storage_reg = name_reg; |
| 841 | 852 |
| 842 if (FLAG_track_fields && representation.IsSmi()) { | 853 if (details.type() == CONSTANT_FUNCTION) { |
| 843 __ JumpIfNotSmi(value_reg, miss_restore_name); | 854 Handle<HeapObject> constant( |
| 855 HeapObject::cast(descriptors->GetValue(descriptor))); |
| 856 __ LoadHeapObject(scratch1, constant); |
| 857 __ cmp(value_reg, scratch1); |
| 858 __ j(not_equal, miss_restore_name); |
| 859 } else if (FLAG_track_fields && representation.IsSmi()) { |
| 860 __ JumpIfNotSmi(value_reg, miss_restore_name); |
| 844 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 861 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| 845 __ JumpIfSmi(value_reg, miss_restore_name); | 862 __ JumpIfSmi(value_reg, miss_restore_name); |
| 846 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 863 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| 847 Label do_store, heap_number; | 864 Label do_store, heap_number; |
| 848 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow); | 865 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow); |
| 849 | 866 |
| 850 __ JumpIfNotSmi(value_reg, &heap_number); | 867 __ JumpIfNotSmi(value_reg, &heap_number); |
| 851 __ SmiUntag(value_reg); | 868 __ SmiUntag(value_reg); |
| 852 if (CpuFeatures::IsSupported(SSE2)) { | 869 if (CpuFeatures::IsSupported(SSE2)) { |
| 853 CpuFeatureScope use_sse2(masm, SSE2); | 870 CpuFeatureScope use_sse2(masm, SSE2); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 877 } else { | 894 } else { |
| 878 __ fstp_d(FieldOperand(storage_reg, HeapNumber::kValueOffset)); | 895 __ fstp_d(FieldOperand(storage_reg, HeapNumber::kValueOffset)); |
| 879 } | 896 } |
| 880 } | 897 } |
| 881 | 898 |
| 882 // Stub never generated for non-global objects that require access | 899 // Stub never generated for non-global objects that require access |
| 883 // checks. | 900 // checks. |
| 884 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 901 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
| 885 | 902 |
| 886 // Perform map transition for the receiver if necessary. | 903 // Perform map transition for the receiver if necessary. |
| 887 if (object->map()->unused_property_fields() == 0) { | 904 if (details.type() == FIELD && |
| 905 object->map()->unused_property_fields() == 0) { |
| 888 // The properties must be extended before we can store the value. | 906 // The properties must be extended before we can store the value. |
| 889 // We jump to a runtime call that extends the properties array. | 907 // We jump to a runtime call that extends the properties array. |
| 890 __ pop(scratch1); // Return address. | 908 __ pop(scratch1); // Return address. |
| 891 __ push(receiver_reg); | 909 __ push(receiver_reg); |
| 892 __ push(Immediate(transition)); | 910 __ push(Immediate(transition)); |
| 893 __ push(value_reg); | 911 __ push(value_reg); |
| 894 __ push(scratch1); | 912 __ push(scratch1); |
| 895 __ TailCallExternalReference( | 913 __ TailCallExternalReference( |
| 896 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 914 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
| 897 masm->isolate()), | 915 masm->isolate()), |
| 898 3, | 916 3, |
| 899 1); | 917 1); |
| 900 return; | 918 return; |
| 901 } | 919 } |
| 902 | 920 |
| 903 // Update the map of the object. | 921 // Update the map of the object. |
| 904 __ mov(scratch1, Immediate(transition)); | 922 __ mov(scratch1, Immediate(transition)); |
| 905 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); | 923 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); |
| 906 | 924 |
| 907 // Update the write barrier for the map field. | 925 // Update the write barrier for the map field. |
| 908 __ RecordWriteField(receiver_reg, | 926 __ RecordWriteField(receiver_reg, |
| 909 HeapObject::kMapOffset, | 927 HeapObject::kMapOffset, |
| 910 scratch1, | 928 scratch1, |
| 911 scratch2, | 929 scratch2, |
| 912 kDontSaveFPRegs, | 930 kDontSaveFPRegs, |
| 913 OMIT_REMEMBERED_SET, | 931 OMIT_REMEMBERED_SET, |
| 914 OMIT_SMI_CHECK); | 932 OMIT_SMI_CHECK); |
| 915 | 933 |
| 934 if (details.type() == CONSTANT_FUNCTION) { |
| 935 ASSERT(value_reg.is(eax)); |
| 936 __ ret(0); |
| 937 return; |
| 938 } |
| 939 |
| 916 int index = transition->instance_descriptors()->GetFieldIndex( | 940 int index = transition->instance_descriptors()->GetFieldIndex( |
| 917 transition->LastAdded()); | 941 transition->LastAdded()); |
| 918 | 942 |
| 919 // Adjust for the number of properties stored in the object. Even in the | 943 // Adjust for the number of properties stored in the object. Even in the |
| 920 // face of a transition we can use the old map here because the size of the | 944 // face of a transition we can use the old map here because the size of the |
| 921 // object and the number of in-object properties is not going to change. | 945 // object and the number of in-object properties is not going to change. |
| 922 index -= object->map()->inobject_properties(); | 946 index -= object->map()->inobject_properties(); |
| 923 | 947 |
| 924 SmiCheck smi_check = representation.IsTagged() | 948 SmiCheck smi_check = representation.IsTagged() |
| 925 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; | 949 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1399 __ push(scratch2()); | 1423 __ push(scratch2()); |
| 1400 | 1424 |
| 1401 __ push(name()); // name | 1425 __ push(name()); // name |
| 1402 __ mov(ebx, esp); // esp points to reference to name (handler). | 1426 __ mov(ebx, esp); // esp points to reference to name (handler). |
| 1403 | 1427 |
| 1404 __ push(scratch3()); // Restore return address. | 1428 __ push(scratch3()); // Restore return address. |
| 1405 | 1429 |
| 1406 // array for v8::Arguments::values_, handler for name and pointer | 1430 // array for v8::Arguments::values_, handler for name and pointer |
| 1407 // to the values (it considered as smi in GC). | 1431 // to the values (it considered as smi in GC). |
| 1408 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 2; | 1432 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 2; |
| 1409 const int kApiArgc = 2; | 1433 // Allocate space for opional callback address parameter in case |
| 1434 // CPU profiler is active. |
| 1435 const int kApiArgc = 2 + 1; |
| 1410 | 1436 |
| 1411 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1437 Address getter_address = v8::ToCData<Address>(callback->getter()); |
| 1412 bool returns_handle = | 1438 bool returns_handle = |
| 1413 !CallbackTable::ReturnsVoid(isolate(), | 1439 !CallbackTable::ReturnsVoid(isolate(), |
| 1414 reinterpret_cast<void*>(getter_address)); | 1440 reinterpret_cast<void*>(getter_address)); |
| 1415 __ PrepareCallApiFunction(kApiArgc, returns_handle); | 1441 __ PrepareCallApiFunction(kApiArgc, returns_handle); |
| 1416 __ mov(ApiParameterOperand(0, returns_handle), ebx); // name. | 1442 __ mov(ApiParameterOperand(0, returns_handle), ebx); // name. |
| 1417 __ add(ebx, Immediate(kPointerSize)); | 1443 __ add(ebx, Immediate(kPointerSize)); |
| 1418 __ mov(ApiParameterOperand(1, returns_handle), ebx); // arguments pointer. | 1444 __ mov(ApiParameterOperand(1, returns_handle), ebx); // arguments pointer. |
| 1419 | 1445 |
| 1420 // Emitting a stub call may try to allocate (if the code is not | 1446 // Emitting a stub call may try to allocate (if the code is not |
| 1421 // already generated). Do not allow the assembler to perform a | 1447 // already generated). Do not allow the assembler to perform a |
| 1422 // garbage collection but instead return the allocation failure | 1448 // garbage collection but instead return the allocation failure |
| 1423 // object. | 1449 // object. |
| 1424 | 1450 |
| 1451 Address thunk_address = returns_handle |
| 1452 ? FUNCTION_ADDR(&InvokeAccessorGetter) |
| 1453 : FUNCTION_ADDR(&InvokeAccessorGetterCallback); |
| 1454 |
| 1425 __ CallApiFunctionAndReturn(getter_address, | 1455 __ CallApiFunctionAndReturn(getter_address, |
| 1456 thunk_address, |
| 1457 ApiParameterOperand(2, returns_handle), |
| 1426 kStackSpace, | 1458 kStackSpace, |
| 1427 returns_handle, | 1459 returns_handle, |
| 1428 6); | 1460 6); |
| 1429 } | 1461 } |
| 1430 | 1462 |
| 1431 | 1463 |
| 1432 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) { | 1464 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) { |
| 1433 // Return the constant value. | 1465 // Return the constant value. |
| 1434 __ LoadHeapObject(eax, value); | 1466 __ LoadHeapObject(eax, value); |
| 1435 __ ret(0); | 1467 __ ret(0); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1558 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1590 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 1559 | 1591 |
| 1560 | 1592 |
| 1561 // Check that the maps haven't changed. | 1593 // Check that the maps haven't changed. |
| 1562 __ JumpIfSmi(edx, miss); | 1594 __ JumpIfSmi(edx, miss); |
| 1563 CheckPrototypes(object, edx, holder, ebx, eax, edi, name, miss); | 1595 CheckPrototypes(object, edx, holder, ebx, eax, edi, name, miss); |
| 1564 } | 1596 } |
| 1565 | 1597 |
| 1566 | 1598 |
| 1567 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1599 void CallStubCompiler::GenerateLoadFunctionFromCell( |
| 1568 Handle<JSGlobalPropertyCell> cell, | 1600 Handle<Cell> cell, |
| 1569 Handle<JSFunction> function, | 1601 Handle<JSFunction> function, |
| 1570 Label* miss) { | 1602 Label* miss) { |
| 1571 // Get the value from the cell. | 1603 // Get the value from the cell. |
| 1572 if (Serializer::enabled()) { | 1604 if (Serializer::enabled()) { |
| 1573 __ mov(edi, Immediate(cell)); | 1605 __ mov(edi, Immediate(cell)); |
| 1574 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); | 1606 __ mov(edi, FieldOperand(edi, Cell::kValueOffset)); |
| 1575 } else { | 1607 } else { |
| 1576 __ mov(edi, Operand::Cell(cell)); | 1608 __ mov(edi, Operand::ForCell(cell)); |
| 1577 } | 1609 } |
| 1578 | 1610 |
| 1579 // Check that the cell contains the same function. | 1611 // Check that the cell contains the same function. |
| 1580 if (isolate()->heap()->InNewSpace(*function)) { | 1612 if (isolate()->heap()->InNewSpace(*function)) { |
| 1581 // We can't embed a pointer to a function in new space so we have | 1613 // We can't embed a pointer to a function in new space so we have |
| 1582 // to verify that the shared function info is unchanged. This has | 1614 // to verify that the shared function info is unchanged. This has |
| 1583 // the nice side effect that multiple closures based on the same | 1615 // the nice side effect that multiple closures based on the same |
| 1584 // function can all use this call IC. Before we load through the | 1616 // function can all use this call IC. Before we load through the |
| 1585 // function, we have to verify that it still is a function. | 1617 // function, we have to verify that it still is a function. |
| 1586 __ JumpIfSmi(edi, miss); | 1618 __ JumpIfSmi(edi, miss); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1657 | 1689 |
| 1658 // Handle call cache miss. | 1690 // Handle call cache miss. |
| 1659 __ bind(&miss); | 1691 __ bind(&miss); |
| 1660 GenerateMissBranch(); | 1692 GenerateMissBranch(); |
| 1661 | 1693 |
| 1662 // Return the generated code. | 1694 // Return the generated code. |
| 1663 return GetCode(Code::FIELD, name); | 1695 return GetCode(Code::FIELD, name); |
| 1664 } | 1696 } |
| 1665 | 1697 |
| 1666 | 1698 |
| 1699 Handle<Code> CallStubCompiler::CompileArrayCodeCall( |
| 1700 Handle<Object> object, |
| 1701 Handle<JSObject> holder, |
| 1702 Handle<Cell> cell, |
| 1703 Handle<JSFunction> function, |
| 1704 Handle<String> name, |
| 1705 Code::StubType type) { |
| 1706 Label miss; |
| 1707 |
| 1708 // Check that function is still array |
| 1709 const int argc = arguments().immediate(); |
| 1710 GenerateNameCheck(name, &miss); |
| 1711 |
| 1712 if (cell.is_null()) { |
| 1713 // Get the receiver from the stack. |
| 1714 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 1715 |
| 1716 // Check that the receiver isn't a smi. |
| 1717 __ JumpIfSmi(edx, &miss); |
| 1718 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, |
| 1719 name, &miss); |
| 1720 } else { |
| 1721 ASSERT(cell->value() == *function); |
| 1722 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 1723 &miss); |
| 1724 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1725 } |
| 1726 |
| 1727 Handle<Smi> kind(Smi::FromInt(GetInitialFastElementsKind()), isolate()); |
| 1728 Handle<Cell> kind_feedback_cell = |
| 1729 isolate()->factory()->NewCell(kind); |
| 1730 __ mov(eax, Immediate(argc)); |
| 1731 __ mov(ebx, kind_feedback_cell); |
| 1732 __ mov(edi, function); |
| 1733 |
| 1734 ArrayConstructorStub stub(isolate()); |
| 1735 __ TailCallStub(&stub); |
| 1736 |
| 1737 __ bind(&miss); |
| 1738 GenerateMissBranch(); |
| 1739 |
| 1740 // Return the generated code. |
| 1741 return GetCode(type, name); |
| 1742 } |
| 1743 |
| 1744 |
| 1667 Handle<Code> CallStubCompiler::CompileArrayPushCall( | 1745 Handle<Code> CallStubCompiler::CompileArrayPushCall( |
| 1668 Handle<Object> object, | 1746 Handle<Object> object, |
| 1669 Handle<JSObject> holder, | 1747 Handle<JSObject> holder, |
| 1670 Handle<JSGlobalPropertyCell> cell, | 1748 Handle<Cell> cell, |
| 1671 Handle<JSFunction> function, | 1749 Handle<JSFunction> function, |
| 1672 Handle<String> name) { | 1750 Handle<String> name, |
| 1751 Code::StubType type) { |
| 1673 // ----------- S t a t e ------------- | 1752 // ----------- S t a t e ------------- |
| 1674 // -- ecx : name | 1753 // -- ecx : name |
| 1675 // -- esp[0] : return address | 1754 // -- esp[0] : return address |
| 1676 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1755 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1677 // -- ... | 1756 // -- ... |
| 1678 // -- esp[(argc + 1) * 4] : receiver | 1757 // -- esp[(argc + 1) * 4] : receiver |
| 1679 // ----------------------------------- | 1758 // ----------------------------------- |
| 1680 | 1759 |
| 1681 // If object is not an array, bail out to regular call. | 1760 // If object is not an array, bail out to regular call. |
| 1682 if (!object->IsJSArray() || !cell.is_null()) { | 1761 if (!object->IsJSArray() || !cell.is_null()) { |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1911 __ TailCallExternalReference( | 1990 __ TailCallExternalReference( |
| 1912 ExternalReference(Builtins::c_ArrayPush, isolate()), | 1991 ExternalReference(Builtins::c_ArrayPush, isolate()), |
| 1913 argc + 1, | 1992 argc + 1, |
| 1914 1); | 1993 1); |
| 1915 } | 1994 } |
| 1916 | 1995 |
| 1917 __ bind(&miss); | 1996 __ bind(&miss); |
| 1918 GenerateMissBranch(); | 1997 GenerateMissBranch(); |
| 1919 | 1998 |
| 1920 // Return the generated code. | 1999 // Return the generated code. |
| 1921 return GetCode(function); | 2000 return GetCode(type, name); |
| 1922 } | 2001 } |
| 1923 | 2002 |
| 1924 | 2003 |
| 1925 Handle<Code> CallStubCompiler::CompileArrayPopCall( | 2004 Handle<Code> CallStubCompiler::CompileArrayPopCall( |
| 1926 Handle<Object> object, | 2005 Handle<Object> object, |
| 1927 Handle<JSObject> holder, | 2006 Handle<JSObject> holder, |
| 1928 Handle<JSGlobalPropertyCell> cell, | 2007 Handle<Cell> cell, |
| 1929 Handle<JSFunction> function, | 2008 Handle<JSFunction> function, |
| 1930 Handle<String> name) { | 2009 Handle<String> name, |
| 2010 Code::StubType type) { |
| 1931 // ----------- S t a t e ------------- | 2011 // ----------- S t a t e ------------- |
| 1932 // -- ecx : name | 2012 // -- ecx : name |
| 1933 // -- esp[0] : return address | 2013 // -- esp[0] : return address |
| 1934 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2014 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1935 // -- ... | 2015 // -- ... |
| 1936 // -- esp[(argc + 1) * 4] : receiver | 2016 // -- esp[(argc + 1) * 4] : receiver |
| 1937 // ----------------------------------- | 2017 // ----------------------------------- |
| 1938 | 2018 |
| 1939 // If object is not an array, bail out to regular call. | 2019 // If object is not an array, bail out to regular call. |
| 1940 if (!object->IsJSArray() || !cell.is_null()) { | 2020 if (!object->IsJSArray() || !cell.is_null()) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1993 __ bind(&call_builtin); | 2073 __ bind(&call_builtin); |
| 1994 __ TailCallExternalReference( | 2074 __ TailCallExternalReference( |
| 1995 ExternalReference(Builtins::c_ArrayPop, isolate()), | 2075 ExternalReference(Builtins::c_ArrayPop, isolate()), |
| 1996 argc + 1, | 2076 argc + 1, |
| 1997 1); | 2077 1); |
| 1998 | 2078 |
| 1999 __ bind(&miss); | 2079 __ bind(&miss); |
| 2000 GenerateMissBranch(); | 2080 GenerateMissBranch(); |
| 2001 | 2081 |
| 2002 // Return the generated code. | 2082 // Return the generated code. |
| 2003 return GetCode(function); | 2083 return GetCode(type, name); |
| 2004 } | 2084 } |
| 2005 | 2085 |
| 2006 | 2086 |
| 2007 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( | 2087 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( |
| 2008 Handle<Object> object, | 2088 Handle<Object> object, |
| 2009 Handle<JSObject> holder, | 2089 Handle<JSObject> holder, |
| 2010 Handle<JSGlobalPropertyCell> cell, | 2090 Handle<Cell> cell, |
| 2011 Handle<JSFunction> function, | 2091 Handle<JSFunction> function, |
| 2012 Handle<String> name) { | 2092 Handle<String> name, |
| 2093 Code::StubType type) { |
| 2013 // ----------- S t a t e ------------- | 2094 // ----------- S t a t e ------------- |
| 2014 // -- ecx : function name | 2095 // -- ecx : function name |
| 2015 // -- esp[0] : return address | 2096 // -- esp[0] : return address |
| 2016 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2097 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 2017 // -- ... | 2098 // -- ... |
| 2018 // -- esp[(argc + 1) * 4] : receiver | 2099 // -- esp[(argc + 1) * 4] : receiver |
| 2019 // ----------------------------------- | 2100 // ----------------------------------- |
| 2020 | 2101 |
| 2021 // If object is not a string, bail out to regular call. | 2102 // If object is not a string, bail out to regular call. |
| 2022 if (!object->IsString() || !cell.is_null()) { | 2103 if (!object->IsString() || !cell.is_null()) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2077 __ ret((argc + 1) * kPointerSize); | 2158 __ ret((argc + 1) * kPointerSize); |
| 2078 } | 2159 } |
| 2079 | 2160 |
| 2080 __ bind(&miss); | 2161 __ bind(&miss); |
| 2081 // Restore function name in ecx. | 2162 // Restore function name in ecx. |
| 2082 __ Set(ecx, Immediate(name)); | 2163 __ Set(ecx, Immediate(name)); |
| 2083 __ bind(&name_miss); | 2164 __ bind(&name_miss); |
| 2084 GenerateMissBranch(); | 2165 GenerateMissBranch(); |
| 2085 | 2166 |
| 2086 // Return the generated code. | 2167 // Return the generated code. |
| 2087 return GetCode(function); | 2168 return GetCode(type, name); |
| 2088 } | 2169 } |
| 2089 | 2170 |
| 2090 | 2171 |
| 2091 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 2172 Handle<Code> CallStubCompiler::CompileStringCharAtCall( |
| 2092 Handle<Object> object, | 2173 Handle<Object> object, |
| 2093 Handle<JSObject> holder, | 2174 Handle<JSObject> holder, |
| 2094 Handle<JSGlobalPropertyCell> cell, | 2175 Handle<Cell> cell, |
| 2095 Handle<JSFunction> function, | 2176 Handle<JSFunction> function, |
| 2096 Handle<String> name) { | 2177 Handle<String> name, |
| 2178 Code::StubType type) { |
| 2097 // ----------- S t a t e ------------- | 2179 // ----------- S t a t e ------------- |
| 2098 // -- ecx : function name | 2180 // -- ecx : function name |
| 2099 // -- esp[0] : return address | 2181 // -- esp[0] : return address |
| 2100 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2182 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 2101 // -- ... | 2183 // -- ... |
| 2102 // -- esp[(argc + 1) * 4] : receiver | 2184 // -- esp[(argc + 1) * 4] : receiver |
| 2103 // ----------------------------------- | 2185 // ----------------------------------- |
| 2104 | 2186 |
| 2105 // If object is not a string, bail out to regular call. | 2187 // If object is not a string, bail out to regular call. |
| 2106 if (!object->IsString() || !cell.is_null()) { | 2188 if (!object->IsString() || !cell.is_null()) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2163 __ ret((argc + 1) * kPointerSize); | 2245 __ ret((argc + 1) * kPointerSize); |
| 2164 } | 2246 } |
| 2165 | 2247 |
| 2166 __ bind(&miss); | 2248 __ bind(&miss); |
| 2167 // Restore function name in ecx. | 2249 // Restore function name in ecx. |
| 2168 __ Set(ecx, Immediate(name)); | 2250 __ Set(ecx, Immediate(name)); |
| 2169 __ bind(&name_miss); | 2251 __ bind(&name_miss); |
| 2170 GenerateMissBranch(); | 2252 GenerateMissBranch(); |
| 2171 | 2253 |
| 2172 // Return the generated code. | 2254 // Return the generated code. |
| 2173 return GetCode(function); | 2255 return GetCode(type, name); |
| 2174 } | 2256 } |
| 2175 | 2257 |
| 2176 | 2258 |
| 2177 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 2259 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( |
| 2178 Handle<Object> object, | 2260 Handle<Object> object, |
| 2179 Handle<JSObject> holder, | 2261 Handle<JSObject> holder, |
| 2180 Handle<JSGlobalPropertyCell> cell, | 2262 Handle<Cell> cell, |
| 2181 Handle<JSFunction> function, | 2263 Handle<JSFunction> function, |
| 2182 Handle<String> name) { | 2264 Handle<String> name, |
| 2265 Code::StubType type) { |
| 2183 // ----------- S t a t e ------------- | 2266 // ----------- S t a t e ------------- |
| 2184 // -- ecx : function name | 2267 // -- ecx : function name |
| 2185 // -- esp[0] : return address | 2268 // -- esp[0] : return address |
| 2186 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2269 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 2187 // -- ... | 2270 // -- ... |
| 2188 // -- esp[(argc + 1) * 4] : receiver | 2271 // -- esp[(argc + 1) * 4] : receiver |
| 2189 // ----------------------------------- | 2272 // ----------------------------------- |
| 2190 | 2273 |
| 2191 const int argc = arguments().immediate(); | 2274 const int argc = arguments().immediate(); |
| 2192 | 2275 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2239 : CALL_AS_METHOD; | 2322 : CALL_AS_METHOD; |
| 2240 ParameterCount expected(function); | 2323 ParameterCount expected(function); |
| 2241 __ InvokeFunction(function, expected, arguments(), | 2324 __ InvokeFunction(function, expected, arguments(), |
| 2242 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2325 JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 2243 | 2326 |
| 2244 __ bind(&miss); | 2327 __ bind(&miss); |
| 2245 // ecx: function name. | 2328 // ecx: function name. |
| 2246 GenerateMissBranch(); | 2329 GenerateMissBranch(); |
| 2247 | 2330 |
| 2248 // Return the generated code. | 2331 // Return the generated code. |
| 2249 return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); | 2332 return GetCode(type, name); |
| 2250 } | 2333 } |
| 2251 | 2334 |
| 2252 | 2335 |
| 2253 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 2336 Handle<Code> CallStubCompiler::CompileMathFloorCall( |
| 2254 Handle<Object> object, | 2337 Handle<Object> object, |
| 2255 Handle<JSObject> holder, | 2338 Handle<JSObject> holder, |
| 2256 Handle<JSGlobalPropertyCell> cell, | 2339 Handle<Cell> cell, |
| 2257 Handle<JSFunction> function, | 2340 Handle<JSFunction> function, |
| 2258 Handle<String> name) { | 2341 Handle<String> name, |
| 2342 Code::StubType type) { |
| 2259 // ----------- S t a t e ------------- | 2343 // ----------- S t a t e ------------- |
| 2260 // -- ecx : name | 2344 // -- ecx : name |
| 2261 // -- esp[0] : return address | 2345 // -- esp[0] : return address |
| 2262 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2346 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 2263 // -- ... | 2347 // -- ... |
| 2264 // -- esp[(argc + 1) * 4] : receiver | 2348 // -- esp[(argc + 1) * 4] : receiver |
| 2265 // ----------------------------------- | 2349 // ----------------------------------- |
| 2266 | 2350 |
| 2267 if (!CpuFeatures::IsSupported(SSE2)) { | 2351 if (!CpuFeatures::IsSupported(SSE2)) { |
| 2268 return Handle<Code>::null(); | 2352 return Handle<Code>::null(); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 __ bind(&slow); | 2454 __ bind(&slow); |
| 2371 ParameterCount expected(function); | 2455 ParameterCount expected(function); |
| 2372 __ InvokeFunction(function, expected, arguments(), | 2456 __ InvokeFunction(function, expected, arguments(), |
| 2373 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2457 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2374 | 2458 |
| 2375 __ bind(&miss); | 2459 __ bind(&miss); |
| 2376 // ecx: function name. | 2460 // ecx: function name. |
| 2377 GenerateMissBranch(); | 2461 GenerateMissBranch(); |
| 2378 | 2462 |
| 2379 // Return the generated code. | 2463 // Return the generated code. |
| 2380 return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); | 2464 return GetCode(type, name); |
| 2381 } | 2465 } |
| 2382 | 2466 |
| 2383 | 2467 |
| 2384 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 2468 Handle<Code> CallStubCompiler::CompileMathAbsCall( |
| 2385 Handle<Object> object, | 2469 Handle<Object> object, |
| 2386 Handle<JSObject> holder, | 2470 Handle<JSObject> holder, |
| 2387 Handle<JSGlobalPropertyCell> cell, | 2471 Handle<Cell> cell, |
| 2388 Handle<JSFunction> function, | 2472 Handle<JSFunction> function, |
| 2389 Handle<String> name) { | 2473 Handle<String> name, |
| 2474 Code::StubType type) { |
| 2390 // ----------- S t a t e ------------- | 2475 // ----------- S t a t e ------------- |
| 2391 // -- ecx : name | 2476 // -- ecx : name |
| 2392 // -- esp[0] : return address | 2477 // -- esp[0] : return address |
| 2393 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2478 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 2394 // -- ... | 2479 // -- ... |
| 2395 // -- esp[(argc + 1) * 4] : receiver | 2480 // -- esp[(argc + 1) * 4] : receiver |
| 2396 // ----------------------------------- | 2481 // ----------------------------------- |
| 2397 | 2482 |
| 2398 const int argc = arguments().immediate(); | 2483 const int argc = arguments().immediate(); |
| 2399 | 2484 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2476 __ bind(&slow); | 2561 __ bind(&slow); |
| 2477 ParameterCount expected(function); | 2562 ParameterCount expected(function); |
| 2478 __ InvokeFunction(function, expected, arguments(), | 2563 __ InvokeFunction(function, expected, arguments(), |
| 2479 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2564 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2480 | 2565 |
| 2481 __ bind(&miss); | 2566 __ bind(&miss); |
| 2482 // ecx: function name. | 2567 // ecx: function name. |
| 2483 GenerateMissBranch(); | 2568 GenerateMissBranch(); |
| 2484 | 2569 |
| 2485 // Return the generated code. | 2570 // Return the generated code. |
| 2486 return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); | 2571 return GetCode(type, name); |
| 2487 } | 2572 } |
| 2488 | 2573 |
| 2489 | 2574 |
| 2490 Handle<Code> CallStubCompiler::CompileFastApiCall( | 2575 Handle<Code> CallStubCompiler::CompileFastApiCall( |
| 2491 const CallOptimization& optimization, | 2576 const CallOptimization& optimization, |
| 2492 Handle<Object> object, | 2577 Handle<Object> object, |
| 2493 Handle<JSObject> holder, | 2578 Handle<JSObject> holder, |
| 2494 Handle<JSGlobalPropertyCell> cell, | 2579 Handle<Cell> cell, |
| 2495 Handle<JSFunction> function, | 2580 Handle<JSFunction> function, |
| 2496 Handle<String> name) { | 2581 Handle<String> name) { |
| 2497 ASSERT(optimization.is_simple_api_call()); | 2582 ASSERT(optimization.is_simple_api_call()); |
| 2498 // Bail out if object is a global object as we don't want to | 2583 // Bail out if object is a global object as we don't want to |
| 2499 // repatch it to global receiver. | 2584 // repatch it to global receiver. |
| 2500 if (object->IsGlobalObject()) return Handle<Code>::null(); | 2585 if (object->IsGlobalObject()) return Handle<Code>::null(); |
| 2501 if (!cell.is_null()) return Handle<Code>::null(); | 2586 if (!cell.is_null()) return Handle<Code>::null(); |
| 2502 if (!object->IsJSObject()) return Handle<Code>::null(); | 2587 if (!object->IsJSObject()) return Handle<Code>::null(); |
| 2503 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2588 int depth = optimization.GetPrototypeDepthOfExpectedType( |
| 2504 Handle<JSObject>::cast(object), holder); | 2589 Handle<JSObject>::cast(object), holder); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2666 | 2751 |
| 2667 Handle<Code> CallStubCompiler::CompileCallConstant( | 2752 Handle<Code> CallStubCompiler::CompileCallConstant( |
| 2668 Handle<Object> object, | 2753 Handle<Object> object, |
| 2669 Handle<JSObject> holder, | 2754 Handle<JSObject> holder, |
| 2670 Handle<Name> name, | 2755 Handle<Name> name, |
| 2671 CheckType check, | 2756 CheckType check, |
| 2672 Handle<JSFunction> function) { | 2757 Handle<JSFunction> function) { |
| 2673 | 2758 |
| 2674 if (HasCustomCallGenerator(function)) { | 2759 if (HasCustomCallGenerator(function)) { |
| 2675 Handle<Code> code = CompileCustomCall(object, holder, | 2760 Handle<Code> code = CompileCustomCall(object, holder, |
| 2676 Handle<JSGlobalPropertyCell>::null(), | 2761 Handle<Cell>::null(), |
| 2677 function, Handle<String>::cast(name)); | 2762 function, Handle<String>::cast(name), |
| 2763 Code::CONSTANT_FUNCTION); |
| 2678 // A null handle means bail out to the regular compiler code below. | 2764 // A null handle means bail out to the regular compiler code below. |
| 2679 if (!code.is_null()) return code; | 2765 if (!code.is_null()) return code; |
| 2680 } | 2766 } |
| 2681 | 2767 |
| 2682 Label success; | 2768 Label success; |
| 2683 | 2769 |
| 2684 CompileHandlerFrontend(object, holder, name, check, &success); | 2770 CompileHandlerFrontend(object, holder, name, check, &success); |
| 2685 __ bind(&success); | 2771 __ bind(&success); |
| 2686 CompileHandlerBackend(function); | 2772 CompileHandlerBackend(function); |
| 2687 | 2773 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2745 GenerateMissBranch(); | 2831 GenerateMissBranch(); |
| 2746 | 2832 |
| 2747 // Return the generated code. | 2833 // Return the generated code. |
| 2748 return GetCode(Code::INTERCEPTOR, name); | 2834 return GetCode(Code::INTERCEPTOR, name); |
| 2749 } | 2835 } |
| 2750 | 2836 |
| 2751 | 2837 |
| 2752 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2838 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2753 Handle<JSObject> object, | 2839 Handle<JSObject> object, |
| 2754 Handle<GlobalObject> holder, | 2840 Handle<GlobalObject> holder, |
| 2755 Handle<JSGlobalPropertyCell> cell, | 2841 Handle<PropertyCell> cell, |
| 2756 Handle<JSFunction> function, | 2842 Handle<JSFunction> function, |
| 2757 Handle<Name> name) { | 2843 Handle<Name> name) { |
| 2758 // ----------- S t a t e ------------- | 2844 // ----------- S t a t e ------------- |
| 2759 // -- ecx : name | 2845 // -- ecx : name |
| 2760 // -- esp[0] : return address | 2846 // -- esp[0] : return address |
| 2761 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2847 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 2762 // -- ... | 2848 // -- ... |
| 2763 // -- esp[(argc + 1) * 4] : receiver | 2849 // -- esp[(argc + 1) * 4] : receiver |
| 2764 // ----------------------------------- | 2850 // ----------------------------------- |
| 2765 | 2851 |
| 2766 if (HasCustomCallGenerator(function)) { | 2852 if (HasCustomCallGenerator(function)) { |
| 2767 Handle<Code> code = CompileCustomCall( | 2853 Handle<Code> code = CompileCustomCall( |
| 2768 object, holder, cell, function, Handle<String>::cast(name)); | 2854 object, holder, cell, function, Handle<String>::cast(name), |
| 2855 Code::NORMAL); |
| 2769 // A null handle means bail out to the regular compiler code below. | 2856 // A null handle means bail out to the regular compiler code below. |
| 2770 if (!code.is_null()) return code; | 2857 if (!code.is_null()) return code; |
| 2771 } | 2858 } |
| 2772 | 2859 |
| 2773 Label miss; | 2860 Label miss; |
| 2774 GenerateNameCheck(name, &miss); | 2861 GenerateNameCheck(name, &miss); |
| 2775 | 2862 |
| 2776 // Get the number of arguments. | 2863 // Get the number of arguments. |
| 2777 const int argc = arguments().immediate(); | 2864 const int argc = arguments().immediate(); |
| 2778 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2865 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2928 __ bind(&miss); | 3015 __ bind(&miss); |
| 2929 TailCallBuiltin(masm(), MissBuiltin(kind())); | 3016 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2930 | 3017 |
| 2931 // Return the generated code. | 3018 // Return the generated code. |
| 2932 return GetICCode(kind(), Code::INTERCEPTOR, name); | 3019 return GetICCode(kind(), Code::INTERCEPTOR, name); |
| 2933 } | 3020 } |
| 2934 | 3021 |
| 2935 | 3022 |
| 2936 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 3023 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
| 2937 Handle<GlobalObject> object, | 3024 Handle<GlobalObject> object, |
| 2938 Handle<JSGlobalPropertyCell> cell, | 3025 Handle<PropertyCell> cell, |
| 2939 Handle<Name> name) { | 3026 Handle<Name> name) { |
| 2940 Label miss; | 3027 Label miss; |
| 2941 | 3028 |
| 2942 // Check that the map of the global has not changed. | 3029 // Check that the map of the global has not changed. |
| 2943 __ cmp(FieldOperand(receiver(), HeapObject::kMapOffset), | 3030 __ cmp(FieldOperand(receiver(), HeapObject::kMapOffset), |
| 2944 Immediate(Handle<Map>(object->map()))); | 3031 Immediate(Handle<Map>(object->map()))); |
| 2945 __ j(not_equal, &miss); | 3032 __ j(not_equal, &miss); |
| 2946 | 3033 |
| 2947 // Compute the cell operand to use. | 3034 // Compute the cell operand to use. |
| 2948 __ mov(scratch1(), Immediate(cell)); | 3035 __ mov(scratch1(), Immediate(cell)); |
| 2949 Operand cell_operand = | 3036 Operand cell_operand = |
| 2950 FieldOperand(scratch1(), JSGlobalPropertyCell::kValueOffset); | 3037 FieldOperand(scratch1(), PropertyCell::kValueOffset); |
| 2951 | 3038 |
| 2952 // Check that the value in the cell is not the hole. If it is, this | 3039 // Check that the value in the cell is not the hole. If it is, this |
| 2953 // cell could have been deleted and reintroducing the global needs | 3040 // cell could have been deleted and reintroducing the global needs |
| 2954 // to update the property details in the property dictionary of the | 3041 // to update the property details in the property dictionary of the |
| 2955 // global object. We bail out to the runtime system to do that. | 3042 // global object. We bail out to the runtime system to do that. |
| 2956 __ cmp(cell_operand, factory()->the_hole_value()); | 3043 __ cmp(cell_operand, factory()->the_hole_value()); |
| 2957 __ j(equal, &miss); | 3044 __ j(equal, &miss); |
| 2958 | 3045 |
| 2959 // Store the value in the cell. | 3046 // Store the value in the cell. |
| 2960 __ mov(cell_operand, value()); | 3047 __ mov(cell_operand, value()); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3101 } | 3188 } |
| 3102 | 3189 |
| 3103 | 3190 |
| 3104 #undef __ | 3191 #undef __ |
| 3105 #define __ ACCESS_MASM(masm()) | 3192 #define __ ACCESS_MASM(masm()) |
| 3106 | 3193 |
| 3107 | 3194 |
| 3108 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 3195 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
| 3109 Handle<JSObject> object, | 3196 Handle<JSObject> object, |
| 3110 Handle<GlobalObject> global, | 3197 Handle<GlobalObject> global, |
| 3111 Handle<JSGlobalPropertyCell> cell, | 3198 Handle<PropertyCell> cell, |
| 3112 Handle<Name> name, | 3199 Handle<Name> name, |
| 3113 bool is_dont_delete) { | 3200 bool is_dont_delete) { |
| 3114 Label success, miss; | 3201 Label success, miss; |
| 3115 | 3202 |
| 3116 __ CheckMap(receiver(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK); | 3203 __ CheckMap(receiver(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK); |
| 3117 HandlerFrontendHeader( | 3204 HandlerFrontendHeader( |
| 3118 object, receiver(), Handle<JSObject>::cast(global), name, &miss); | 3205 object, receiver(), Handle<JSObject>::cast(global), name, &miss); |
| 3119 // Get the value from the cell. | 3206 // Get the value from the cell. |
| 3120 if (Serializer::enabled()) { | 3207 if (Serializer::enabled()) { |
| 3121 __ mov(eax, Immediate(cell)); | 3208 __ mov(eax, Immediate(cell)); |
| 3122 __ mov(eax, FieldOperand(eax, JSGlobalPropertyCell::kValueOffset)); | 3209 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset)); |
| 3123 } else { | 3210 } else { |
| 3124 __ mov(eax, Operand::Cell(cell)); | 3211 __ mov(eax, Operand::ForCell(cell)); |
| 3125 } | 3212 } |
| 3126 | 3213 |
| 3127 // Check for deleted property if property can actually be deleted. | 3214 // Check for deleted property if property can actually be deleted. |
| 3128 if (!is_dont_delete) { | 3215 if (!is_dont_delete) { |
| 3129 __ cmp(eax, factory()->the_hole_value()); | 3216 __ cmp(eax, factory()->the_hole_value()); |
| 3130 __ j(equal, &miss); | 3217 __ j(equal, &miss); |
| 3131 } else if (FLAG_debug_code) { | 3218 } else if (FLAG_debug_code) { |
| 3132 __ cmp(eax, factory()->the_hole_value()); | 3219 __ cmp(eax, factory()->the_hole_value()); |
| 3133 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 3220 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
| 3134 } | 3221 } |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3743 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3830 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
| 3744 } | 3831 } |
| 3745 } | 3832 } |
| 3746 | 3833 |
| 3747 | 3834 |
| 3748 #undef __ | 3835 #undef __ |
| 3749 | 3836 |
| 3750 } } // namespace v8::internal | 3837 } } // namespace v8::internal |
| 3751 | 3838 |
| 3752 #endif // V8_TARGET_ARCH_IA32 | 3839 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |