| 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 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 STATIC_ASSERT(kFastApiCallArguments == 6); | 484 STATIC_ASSERT(kFastApiCallArguments == 6); |
| 485 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); | 485 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); |
| 486 | 486 |
| 487 // Function address is a foreign pointer outside V8's heap. | 487 // Function address is a foreign pointer outside V8's heap. |
| 488 Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 488 Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
| 489 bool returns_handle = | 489 bool returns_handle = |
| 490 !CallbackTable::ReturnsVoid(masm->isolate(), function_address); | 490 !CallbackTable::ReturnsVoid(masm->isolate(), function_address); |
| 491 | 491 |
| 492 #if defined(__MINGW64__) | 492 #if defined(__MINGW64__) |
| 493 Register arguments_arg = rcx; | 493 Register arguments_arg = rcx; |
| 494 Register callback_arg = rdx; |
| 494 #elif defined(_WIN64) | 495 #elif defined(_WIN64) |
| 495 // Win64 uses first register--rcx--for returned value. | 496 // Win64 uses first register--rcx--for returned value. |
| 496 Register arguments_arg = returns_handle ? rdx : rcx; | 497 Register arguments_arg = returns_handle ? rdx : rcx; |
| 498 Register callback_arg = returns_handle ? r8 : rdx; |
| 497 #else | 499 #else |
| 498 Register arguments_arg = rdi; | 500 Register arguments_arg = rdi; |
| 501 Register callback_arg = rsi; |
| 499 #endif | 502 #endif |
| 500 | 503 |
| 501 // Allocate the v8::Arguments structure in the arguments' space since | 504 // Allocate the v8::Arguments structure in the arguments' space since |
| 502 // it's not controlled by GC. | 505 // it's not controlled by GC. |
| 503 const int kApiStackSpace = 4; | 506 const int kApiStackSpace = 4; |
| 504 | 507 |
| 505 __ PrepareCallApiFunction(kApiStackSpace, returns_handle); | 508 __ PrepareCallApiFunction(kApiStackSpace, returns_handle); |
| 506 | 509 |
| 507 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_. | 510 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_. |
| 508 __ addq(rbx, Immediate(argc * kPointerSize)); | 511 __ addq(rbx, Immediate(argc * kPointerSize)); |
| 509 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_. | 512 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_. |
| 510 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_. | 513 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_. |
| 511 // v8::Arguments::is_construct_call_. | 514 // v8::Arguments::is_construct_call_. |
| 512 __ Set(StackSpaceOperand(3), 0); | 515 __ Set(StackSpaceOperand(3), 0); |
| 513 | 516 |
| 514 // v8::InvocationCallback's argument. | 517 // v8::InvocationCallback's argument. |
| 515 __ lea(arguments_arg, StackSpaceOperand(0)); | 518 __ lea(arguments_arg, StackSpaceOperand(0)); |
| 516 | 519 |
| 520 Address thunk_address = returns_handle |
| 521 ? FUNCTION_ADDR(&InvokeInvocationCallback) |
| 522 : FUNCTION_ADDR(&InvokeFunctionCallback); |
| 523 |
| 517 __ CallApiFunctionAndReturn(function_address, | 524 __ CallApiFunctionAndReturn(function_address, |
| 525 thunk_address, |
| 526 callback_arg, |
| 518 argc + kFastApiCallArguments + 1, | 527 argc + kFastApiCallArguments + 1, |
| 519 returns_handle, | 528 returns_handle, |
| 520 kFastApiCallArguments + 1); | 529 kFastApiCallArguments + 1); |
| 521 } | 530 } |
| 522 | 531 |
| 523 | 532 |
| 524 class CallInterceptorCompiler BASE_EMBEDDED { | 533 class CallInterceptorCompiler BASE_EMBEDDED { |
| 525 public: | 534 public: |
| 526 CallInterceptorCompiler(StubCompiler* stub_compiler, | 535 CallInterceptorCompiler(StubCompiler* stub_compiler, |
| 527 const ParameterCount& arguments, | 536 const ParameterCount& arguments, |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 | 739 |
| 731 | 740 |
| 732 // Generate code to check that a global property cell is empty. Create | 741 // Generate code to check that a global property cell is empty. Create |
| 733 // the property cell at compilation time if no cell exists for the | 742 // the property cell at compilation time if no cell exists for the |
| 734 // property. | 743 // property. |
| 735 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 744 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 736 Handle<GlobalObject> global, | 745 Handle<GlobalObject> global, |
| 737 Handle<Name> name, | 746 Handle<Name> name, |
| 738 Register scratch, | 747 Register scratch, |
| 739 Label* miss) { | 748 Label* miss) { |
| 740 Handle<JSGlobalPropertyCell> cell = | 749 Handle<PropertyCell> cell = |
| 741 GlobalObject::EnsurePropertyCell(global, name); | 750 GlobalObject::EnsurePropertyCell(global, name); |
| 742 ASSERT(cell->value()->IsTheHole()); | 751 ASSERT(cell->value()->IsTheHole()); |
| 743 __ Move(scratch, cell); | 752 __ Move(scratch, cell); |
| 744 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 753 __ Cmp(FieldOperand(scratch, Cell::kValueOffset), |
| 745 masm->isolate()->factory()->the_hole_value()); | 754 masm->isolate()->factory()->the_hole_value()); |
| 746 __ j(not_equal, miss); | 755 __ j(not_equal, miss); |
| 747 } | 756 } |
| 748 | 757 |
| 749 | 758 |
| 750 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 759 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
| 751 // but may be destroyed if store is successful. | 760 // but may be destroyed if store is successful. |
| 752 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, | 761 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
| 753 Handle<JSObject> object, | 762 Handle<JSObject> object, |
| 754 LookupResult* lookup, | 763 LookupResult* lookup, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 miss_restore_name); | 819 miss_restore_name); |
| 811 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { | 820 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { |
| 812 GenerateDictionaryNegativeLookup( | 821 GenerateDictionaryNegativeLookup( |
| 813 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); | 822 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); |
| 814 } | 823 } |
| 815 } | 824 } |
| 816 } | 825 } |
| 817 | 826 |
| 818 Register storage_reg = name_reg; | 827 Register storage_reg = name_reg; |
| 819 | 828 |
| 820 if (FLAG_track_fields && representation.IsSmi()) { | 829 if (details.type() == CONSTANT_FUNCTION) { |
| 830 Handle<HeapObject> constant( |
| 831 HeapObject::cast(descriptors->GetValue(descriptor))); |
| 832 __ LoadHeapObject(scratch1, constant); |
| 833 __ cmpq(value_reg, scratch1); |
| 834 __ j(not_equal, miss_restore_name); |
| 835 } else if (FLAG_track_fields && representation.IsSmi()) { |
| 821 __ JumpIfNotSmi(value_reg, miss_restore_name); | 836 __ JumpIfNotSmi(value_reg, miss_restore_name); |
| 822 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 837 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| 823 __ JumpIfSmi(value_reg, miss_restore_name); | 838 __ JumpIfSmi(value_reg, miss_restore_name); |
| 824 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 839 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| 825 Label do_store, heap_number; | 840 Label do_store, heap_number; |
| 826 __ AllocateHeapNumber(storage_reg, scratch1, slow); | 841 __ AllocateHeapNumber(storage_reg, scratch1, slow); |
| 827 | 842 |
| 828 __ JumpIfNotSmi(value_reg, &heap_number); | 843 __ JumpIfNotSmi(value_reg, &heap_number); |
| 829 __ SmiToInteger32(scratch1, value_reg); | 844 __ SmiToInteger32(scratch1, value_reg); |
| 830 __ cvtlsi2sd(xmm0, scratch1); | 845 __ cvtlsi2sd(xmm0, scratch1); |
| 831 __ jmp(&do_store); | 846 __ jmp(&do_store); |
| 832 | 847 |
| 833 __ bind(&heap_number); | 848 __ bind(&heap_number); |
| 834 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), | 849 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
| 835 miss_restore_name, DONT_DO_SMI_CHECK); | 850 miss_restore_name, DONT_DO_SMI_CHECK); |
| 836 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); | 851 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); |
| 837 | 852 |
| 838 __ bind(&do_store); | 853 __ bind(&do_store); |
| 839 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); | 854 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); |
| 840 } | 855 } |
| 841 | 856 |
| 842 // Stub never generated for non-global objects that require access | 857 // Stub never generated for non-global objects that require access |
| 843 // checks. | 858 // checks. |
| 844 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 859 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
| 845 | 860 |
| 846 // Perform map transition for the receiver if necessary. | 861 // Perform map transition for the receiver if necessary. |
| 847 if (object->map()->unused_property_fields() == 0) { | 862 if (details.type() == FIELD && |
| 863 object->map()->unused_property_fields() == 0) { |
| 848 // The properties must be extended before we can store the value. | 864 // The properties must be extended before we can store the value. |
| 849 // We jump to a runtime call that extends the properties array. | 865 // We jump to a runtime call that extends the properties array. |
| 850 __ pop(scratch1); // Return address. | 866 __ pop(scratch1); // Return address. |
| 851 __ push(receiver_reg); | 867 __ push(receiver_reg); |
| 852 __ Push(transition); | 868 __ Push(transition); |
| 853 __ push(value_reg); | 869 __ push(value_reg); |
| 854 __ push(scratch1); | 870 __ push(scratch1); |
| 855 __ TailCallExternalReference( | 871 __ TailCallExternalReference( |
| 856 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 872 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
| 857 masm->isolate()), | 873 masm->isolate()), |
| 858 3, | 874 3, |
| 859 1); | 875 1); |
| 860 return; | 876 return; |
| 861 } | 877 } |
| 862 | 878 |
| 863 // Update the map of the object. | 879 // Update the map of the object. |
| 864 __ Move(scratch1, transition); | 880 __ Move(scratch1, transition); |
| 865 __ movq(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); | 881 __ movq(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); |
| 866 | 882 |
| 867 // Update the write barrier for the map field. | 883 // Update the write barrier for the map field. |
| 868 __ RecordWriteField(receiver_reg, | 884 __ RecordWriteField(receiver_reg, |
| 869 HeapObject::kMapOffset, | 885 HeapObject::kMapOffset, |
| 870 scratch1, | 886 scratch1, |
| 871 scratch2, | 887 scratch2, |
| 872 kDontSaveFPRegs, | 888 kDontSaveFPRegs, |
| 873 OMIT_REMEMBERED_SET, | 889 OMIT_REMEMBERED_SET, |
| 874 OMIT_SMI_CHECK); | 890 OMIT_SMI_CHECK); |
| 875 | 891 |
| 892 if (details.type() == CONSTANT_FUNCTION) { |
| 893 ASSERT(value_reg.is(rax)); |
| 894 __ ret(0); |
| 895 return; |
| 896 } |
| 897 |
| 876 int index = transition->instance_descriptors()->GetFieldIndex( | 898 int index = transition->instance_descriptors()->GetFieldIndex( |
| 877 transition->LastAdded()); | 899 transition->LastAdded()); |
| 878 | 900 |
| 879 // Adjust for the number of properties stored in the object. Even in the | 901 // Adjust for the number of properties stored in the object. Even in the |
| 880 // face of a transition we can use the old map here because the size of the | 902 // face of a transition we can use the old map here because the size of the |
| 881 // object and the number of in-object properties is not going to change. | 903 // object and the number of in-object properties is not going to change. |
| 882 index -= object->map()->inobject_properties(); | 904 index -= object->map()->inobject_properties(); |
| 883 | 905 |
| 884 // TODO(verwaest): Share this code as a code stub. | 906 // TODO(verwaest): Share this code as a code stub. |
| 885 SmiCheck smi_check = representation.IsTagged() | 907 SmiCheck smi_check = representation.IsTagged() |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1311 __ PushAddress(ExternalReference::isolate_address(isolate())); | 1333 __ PushAddress(ExternalReference::isolate_address(isolate())); |
| 1312 __ push(name()); // name | 1334 __ push(name()); // name |
| 1313 // Save a pointer to where we pushed the arguments pointer. This will be | 1335 // Save a pointer to where we pushed the arguments pointer. This will be |
| 1314 // passed as the const ExecutableAccessorInfo& to the C++ callback. | 1336 // passed as the const ExecutableAccessorInfo& to the C++ callback. |
| 1315 | 1337 |
| 1316 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1338 Address getter_address = v8::ToCData<Address>(callback->getter()); |
| 1317 bool returns_handle = | 1339 bool returns_handle = |
| 1318 !CallbackTable::ReturnsVoid(isolate(), getter_address); | 1340 !CallbackTable::ReturnsVoid(isolate(), getter_address); |
| 1319 | 1341 |
| 1320 #if defined(__MINGW64__) | 1342 #if defined(__MINGW64__) |
| 1343 Register getter_arg = r8; |
| 1321 Register accessor_info_arg = rdx; | 1344 Register accessor_info_arg = rdx; |
| 1322 Register name_arg = rcx; | 1345 Register name_arg = rcx; |
| 1323 #elif defined(_WIN64) | 1346 #elif defined(_WIN64) |
| 1324 // Win64 uses first register--rcx--for returned value. | 1347 // Win64 uses first register--rcx--for returned value. |
| 1348 Register getter_arg = returns_handle ? r9 : r8; |
| 1325 Register accessor_info_arg = returns_handle ? r8 : rdx; | 1349 Register accessor_info_arg = returns_handle ? r8 : rdx; |
| 1326 Register name_arg = returns_handle ? rdx : rcx; | 1350 Register name_arg = returns_handle ? rdx : rcx; |
| 1327 #else | 1351 #else |
| 1352 Register getter_arg = rdx; |
| 1328 Register accessor_info_arg = rsi; | 1353 Register accessor_info_arg = rsi; |
| 1329 Register name_arg = rdi; | 1354 Register name_arg = rdi; |
| 1330 #endif | 1355 #endif |
| 1331 | 1356 |
| 1332 ASSERT(!name_arg.is(scratch2())); | 1357 ASSERT(!name_arg.is(scratch2())); |
| 1333 __ movq(name_arg, rsp); | 1358 __ movq(name_arg, rsp); |
| 1334 __ push(scratch2()); // Restore return address. | 1359 __ push(scratch2()); // Restore return address. |
| 1335 | 1360 |
| 1336 // v8::Arguments::values_ and handler for name. | 1361 // v8::Arguments::values_ and handler for name. |
| 1337 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1; | 1362 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1; |
| 1338 | 1363 |
| 1339 // Allocate v8::AccessorInfo in non-GCed stack space. | 1364 // Allocate v8::AccessorInfo in non-GCed stack space. |
| 1340 const int kArgStackSpace = 1; | 1365 const int kArgStackSpace = 1; |
| 1341 | 1366 |
| 1342 __ PrepareCallApiFunction(kArgStackSpace, returns_handle); | 1367 __ PrepareCallApiFunction(kArgStackSpace, returns_handle); |
| 1343 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); | 1368 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); |
| 1344 __ lea(rax, Operand(name_arg, 6 * kPointerSize)); | 1369 __ lea(rax, Operand(name_arg, 6 * kPointerSize)); |
| 1345 | 1370 |
| 1346 // v8::AccessorInfo::args_. | 1371 // v8::AccessorInfo::args_. |
| 1347 __ movq(StackSpaceOperand(0), rax); | 1372 __ movq(StackSpaceOperand(0), rax); |
| 1348 | 1373 |
| 1349 // The context register (rsi) has been saved in PrepareCallApiFunction and | 1374 // The context register (rsi) has been saved in PrepareCallApiFunction and |
| 1350 // could be used to pass arguments. | 1375 // could be used to pass arguments. |
| 1351 __ lea(accessor_info_arg, StackSpaceOperand(0)); | 1376 __ lea(accessor_info_arg, StackSpaceOperand(0)); |
| 1352 | 1377 |
| 1378 Address thunk_address = returns_handle |
| 1379 ? FUNCTION_ADDR(&InvokeAccessorGetter) |
| 1380 : FUNCTION_ADDR(&InvokeAccessorGetterCallback); |
| 1381 |
| 1353 __ CallApiFunctionAndReturn(getter_address, | 1382 __ CallApiFunctionAndReturn(getter_address, |
| 1383 thunk_address, |
| 1384 getter_arg, |
| 1354 kStackSpace, | 1385 kStackSpace, |
| 1355 returns_handle, | 1386 returns_handle, |
| 1356 5); | 1387 5); |
| 1357 } | 1388 } |
| 1358 | 1389 |
| 1359 | 1390 |
| 1360 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) { | 1391 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<JSFunction> value) { |
| 1361 // Return the constant value. | 1392 // Return the constant value. |
| 1362 __ LoadHeapObject(rax, value); | 1393 __ LoadHeapObject(rax, value); |
| 1363 __ ret(0); | 1394 __ ret(0); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1478 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1509 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
| 1479 | 1510 |
| 1480 | 1511 |
| 1481 // Check that the maps haven't changed. | 1512 // Check that the maps haven't changed. |
| 1482 __ JumpIfSmi(rdx, miss); | 1513 __ JumpIfSmi(rdx, miss); |
| 1483 CheckPrototypes(object, rdx, holder, rbx, rax, rdi, name, miss); | 1514 CheckPrototypes(object, rdx, holder, rbx, rax, rdi, name, miss); |
| 1484 } | 1515 } |
| 1485 | 1516 |
| 1486 | 1517 |
| 1487 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1518 void CallStubCompiler::GenerateLoadFunctionFromCell( |
| 1488 Handle<JSGlobalPropertyCell> cell, | 1519 Handle<Cell> cell, |
| 1489 Handle<JSFunction> function, | 1520 Handle<JSFunction> function, |
| 1490 Label* miss) { | 1521 Label* miss) { |
| 1491 // Get the value from the cell. | 1522 // Get the value from the cell. |
| 1492 __ Move(rdi, cell); | 1523 __ Move(rdi, cell); |
| 1493 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); | 1524 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); |
| 1494 | 1525 |
| 1495 // Check that the cell contains the same function. | 1526 // Check that the cell contains the same function. |
| 1496 if (heap()->InNewSpace(*function)) { | 1527 if (heap()->InNewSpace(*function)) { |
| 1497 // We can't embed a pointer to a function in new space so we have | 1528 // We can't embed a pointer to a function in new space so we have |
| 1498 // to verify that the shared function info is unchanged. This has | 1529 // to verify that the shared function info is unchanged. This has |
| 1499 // the nice side effect that multiple closures based on the same | 1530 // the nice side effect that multiple closures based on the same |
| 1500 // function can all use this call IC. Before we load through the | 1531 // function can all use this call IC. Before we load through the |
| 1501 // function, we have to verify that it still is a function. | 1532 // function, we have to verify that it still is a function. |
| 1502 __ JumpIfSmi(rdi, miss); | 1533 __ JumpIfSmi(rdi, miss); |
| 1503 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax); | 1534 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1574 | 1605 |
| 1575 // Handle call cache miss. | 1606 // Handle call cache miss. |
| 1576 __ bind(&miss); | 1607 __ bind(&miss); |
| 1577 GenerateMissBranch(); | 1608 GenerateMissBranch(); |
| 1578 | 1609 |
| 1579 // Return the generated code. | 1610 // Return the generated code. |
| 1580 return GetCode(Code::FIELD, name); | 1611 return GetCode(Code::FIELD, name); |
| 1581 } | 1612 } |
| 1582 | 1613 |
| 1583 | 1614 |
| 1615 Handle<Code> CallStubCompiler::CompileArrayCodeCall( |
| 1616 Handle<Object> object, |
| 1617 Handle<JSObject> holder, |
| 1618 Handle<Cell> cell, |
| 1619 Handle<JSFunction> function, |
| 1620 Handle<String> name, |
| 1621 Code::StubType type) { |
| 1622 Label miss; |
| 1623 |
| 1624 // Check that function is still array |
| 1625 const int argc = arguments().immediate(); |
| 1626 GenerateNameCheck(name, &miss); |
| 1627 |
| 1628 if (cell.is_null()) { |
| 1629 // Get the receiver from the stack. |
| 1630 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
| 1631 |
| 1632 // Check that the receiver isn't a smi. |
| 1633 __ JumpIfSmi(rdx, &miss); |
| 1634 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, |
| 1635 name, &miss); |
| 1636 } else { |
| 1637 ASSERT(cell->value() == *function); |
| 1638 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 1639 &miss); |
| 1640 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1641 } |
| 1642 |
| 1643 Handle<Smi> kind(Smi::FromInt(GetInitialFastElementsKind()), isolate()); |
| 1644 Handle<Cell> kind_feedback_cell = |
| 1645 isolate()->factory()->NewCell(kind); |
| 1646 __ movq(rax, Immediate(argc)); |
| 1647 __ Move(rbx, kind_feedback_cell); |
| 1648 __ Move(rdi, function); |
| 1649 |
| 1650 ArrayConstructorStub stub(isolate()); |
| 1651 __ TailCallStub(&stub); |
| 1652 |
| 1653 __ bind(&miss); |
| 1654 GenerateMissBranch(); |
| 1655 |
| 1656 // Return the generated code. |
| 1657 return GetCode(type, name); |
| 1658 } |
| 1659 |
| 1660 |
| 1584 Handle<Code> CallStubCompiler::CompileArrayPushCall( | 1661 Handle<Code> CallStubCompiler::CompileArrayPushCall( |
| 1585 Handle<Object> object, | 1662 Handle<Object> object, |
| 1586 Handle<JSObject> holder, | 1663 Handle<JSObject> holder, |
| 1587 Handle<JSGlobalPropertyCell> cell, | 1664 Handle<Cell> cell, |
| 1588 Handle<JSFunction> function, | 1665 Handle<JSFunction> function, |
| 1589 Handle<String> name) { | 1666 Handle<String> name, |
| 1667 Code::StubType type) { |
| 1590 // ----------- S t a t e ------------- | 1668 // ----------- S t a t e ------------- |
| 1591 // -- rcx : name | 1669 // -- rcx : name |
| 1592 // -- rsp[0] : return address | 1670 // -- rsp[0] : return address |
| 1593 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1671 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
| 1594 // -- ... | 1672 // -- ... |
| 1595 // -- rsp[(argc + 1) * 8] : receiver | 1673 // -- rsp[(argc + 1) * 8] : receiver |
| 1596 // ----------------------------------- | 1674 // ----------------------------------- |
| 1597 | 1675 |
| 1598 // If object is not an array, bail out to regular call. | 1676 // If object is not an array, bail out to regular call. |
| 1599 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); | 1677 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1820 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1898 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, |
| 1821 isolate()), | 1899 isolate()), |
| 1822 argc + 1, | 1900 argc + 1, |
| 1823 1); | 1901 1); |
| 1824 } | 1902 } |
| 1825 | 1903 |
| 1826 __ bind(&miss); | 1904 __ bind(&miss); |
| 1827 GenerateMissBranch(); | 1905 GenerateMissBranch(); |
| 1828 | 1906 |
| 1829 // Return the generated code. | 1907 // Return the generated code. |
| 1830 return GetCode(function); | 1908 return GetCode(type, name); |
| 1831 } | 1909 } |
| 1832 | 1910 |
| 1833 | 1911 |
| 1834 Handle<Code> CallStubCompiler::CompileArrayPopCall( | 1912 Handle<Code> CallStubCompiler::CompileArrayPopCall( |
| 1835 Handle<Object> object, | 1913 Handle<Object> object, |
| 1836 Handle<JSObject> holder, | 1914 Handle<JSObject> holder, |
| 1837 Handle<JSGlobalPropertyCell> cell, | 1915 Handle<Cell> cell, |
| 1838 Handle<JSFunction> function, | 1916 Handle<JSFunction> function, |
| 1839 Handle<String> name) { | 1917 Handle<String> name, |
| 1918 Code::StubType type) { |
| 1840 // ----------- S t a t e ------------- | 1919 // ----------- S t a t e ------------- |
| 1841 // -- rcx : name | 1920 // -- rcx : name |
| 1842 // -- rsp[0] : return address | 1921 // -- rsp[0] : return address |
| 1843 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1922 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
| 1844 // -- ... | 1923 // -- ... |
| 1845 // -- rsp[(argc + 1) * 8] : receiver | 1924 // -- rsp[(argc + 1) * 8] : receiver |
| 1846 // ----------------------------------- | 1925 // ----------------------------------- |
| 1847 | 1926 |
| 1848 // If object is not an array, bail out to regular call. | 1927 // If object is not an array, bail out to regular call. |
| 1849 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); | 1928 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 __ bind(&call_builtin); | 1980 __ bind(&call_builtin); |
| 1902 __ TailCallExternalReference( | 1981 __ TailCallExternalReference( |
| 1903 ExternalReference(Builtins::c_ArrayPop, isolate()), | 1982 ExternalReference(Builtins::c_ArrayPop, isolate()), |
| 1904 argc + 1, | 1983 argc + 1, |
| 1905 1); | 1984 1); |
| 1906 | 1985 |
| 1907 __ bind(&miss); | 1986 __ bind(&miss); |
| 1908 GenerateMissBranch(); | 1987 GenerateMissBranch(); |
| 1909 | 1988 |
| 1910 // Return the generated code. | 1989 // Return the generated code. |
| 1911 return GetCode(function); | 1990 return GetCode(type, name); |
| 1912 } | 1991 } |
| 1913 | 1992 |
| 1914 | 1993 |
| 1915 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( | 1994 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( |
| 1916 Handle<Object> object, | 1995 Handle<Object> object, |
| 1917 Handle<JSObject> holder, | 1996 Handle<JSObject> holder, |
| 1918 Handle<JSGlobalPropertyCell> cell, | 1997 Handle<Cell> cell, |
| 1919 Handle<JSFunction> function, | 1998 Handle<JSFunction> function, |
| 1920 Handle<String> name) { | 1999 Handle<String> name, |
| 2000 Code::StubType type) { |
| 1921 // ----------- S t a t e ------------- | 2001 // ----------- S t a t e ------------- |
| 1922 // -- rcx : function name | 2002 // -- rcx : function name |
| 1923 // -- rsp[0] : return address | 2003 // -- rsp[0] : return address |
| 1924 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 2004 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
| 1925 // -- ... | 2005 // -- ... |
| 1926 // -- rsp[(argc + 1) * 8] : receiver | 2006 // -- rsp[(argc + 1) * 8] : receiver |
| 1927 // ----------------------------------- | 2007 // ----------------------------------- |
| 1928 | 2008 |
| 1929 // If object is not a string, bail out to regular call. | 2009 // If object is not a string, bail out to regular call. |
| 1930 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); | 2010 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1981 __ ret((argc + 1) * kPointerSize); | 2061 __ ret((argc + 1) * kPointerSize); |
| 1982 } | 2062 } |
| 1983 | 2063 |
| 1984 __ bind(&miss); | 2064 __ bind(&miss); |
| 1985 // Restore function name in rcx. | 2065 // Restore function name in rcx. |
| 1986 __ Move(rcx, name); | 2066 __ Move(rcx, name); |
| 1987 __ bind(&name_miss); | 2067 __ bind(&name_miss); |
| 1988 GenerateMissBranch(); | 2068 GenerateMissBranch(); |
| 1989 | 2069 |
| 1990 // Return the generated code. | 2070 // Return the generated code. |
| 1991 return GetCode(function); | 2071 return GetCode(type, name); |
| 1992 } | 2072 } |
| 1993 | 2073 |
| 1994 | 2074 |
| 1995 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 2075 Handle<Code> CallStubCompiler::CompileStringCharAtCall( |
| 1996 Handle<Object> object, | 2076 Handle<Object> object, |
| 1997 Handle<JSObject> holder, | 2077 Handle<JSObject> holder, |
| 1998 Handle<JSGlobalPropertyCell> cell, | 2078 Handle<Cell> cell, |
| 1999 Handle<JSFunction> function, | 2079 Handle<JSFunction> function, |
| 2000 Handle<String> name) { | 2080 Handle<String> name, |
| 2081 Code::StubType type) { |
| 2001 // ----------- S t a t e ------------- | 2082 // ----------- S t a t e ------------- |
| 2002 // -- rcx : function name | 2083 // -- rcx : function name |
| 2003 // -- rsp[0] : return address | 2084 // -- rsp[0] : return address |
| 2004 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 2085 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
| 2005 // -- ... | 2086 // -- ... |
| 2006 // -- rsp[(argc + 1) * 8] : receiver | 2087 // -- rsp[(argc + 1) * 8] : receiver |
| 2007 // ----------------------------------- | 2088 // ----------------------------------- |
| 2008 | 2089 |
| 2009 // If object is not a string, bail out to regular call. | 2090 // If object is not a string, bail out to regular call. |
| 2010 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); | 2091 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2061 __ LoadRoot(rax, Heap::kempty_stringRootIndex); | 2142 __ LoadRoot(rax, Heap::kempty_stringRootIndex); |
| 2062 __ ret((argc + 1) * kPointerSize); | 2143 __ ret((argc + 1) * kPointerSize); |
| 2063 } | 2144 } |
| 2064 __ bind(&miss); | 2145 __ bind(&miss); |
| 2065 // Restore function name in rcx. | 2146 // Restore function name in rcx. |
| 2066 __ Move(rcx, name); | 2147 __ Move(rcx, name); |
| 2067 __ bind(&name_miss); | 2148 __ bind(&name_miss); |
| 2068 GenerateMissBranch(); | 2149 GenerateMissBranch(); |
| 2069 | 2150 |
| 2070 // Return the generated code. | 2151 // Return the generated code. |
| 2071 return GetCode(function); | 2152 return GetCode(type, name); |
| 2072 } | 2153 } |
| 2073 | 2154 |
| 2074 | 2155 |
| 2075 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 2156 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( |
| 2076 Handle<Object> object, | 2157 Handle<Object> object, |
| 2077 Handle<JSObject> holder, | 2158 Handle<JSObject> holder, |
| 2078 Handle<JSGlobalPropertyCell> cell, | 2159 Handle<Cell> cell, |
| 2079 Handle<JSFunction> function, | 2160 Handle<JSFunction> function, |
| 2080 Handle<String> name) { | 2161 Handle<String> name, |
| 2162 Code::StubType type) { |
| 2081 // ----------- S t a t e ------------- | 2163 // ----------- S t a t e ------------- |
| 2082 // -- rcx : function name | 2164 // -- rcx : function name |
| 2083 // -- rsp[0] : return address | 2165 // -- rsp[0] : return address |
| 2084 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 2166 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
| 2085 // -- ... | 2167 // -- ... |
| 2086 // -- rsp[(argc + 1) * 8] : receiver | 2168 // -- rsp[(argc + 1) * 8] : receiver |
| 2087 // ----------------------------------- | 2169 // ----------------------------------- |
| 2088 | 2170 |
| 2089 // If the object is not a JSObject or we got an unexpected number of | 2171 // If the object is not a JSObject or we got an unexpected number of |
| 2090 // arguments, bail out to the regular call. | 2172 // arguments, bail out to the regular call. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2132 : CALL_AS_METHOD; | 2214 : CALL_AS_METHOD; |
| 2133 ParameterCount expected(function); | 2215 ParameterCount expected(function); |
| 2134 __ InvokeFunction(function, expected, arguments(), | 2216 __ InvokeFunction(function, expected, arguments(), |
| 2135 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2217 JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 2136 | 2218 |
| 2137 __ bind(&miss); | 2219 __ bind(&miss); |
| 2138 // rcx: function name. | 2220 // rcx: function name. |
| 2139 GenerateMissBranch(); | 2221 GenerateMissBranch(); |
| 2140 | 2222 |
| 2141 // Return the generated code. | 2223 // Return the generated code. |
| 2142 return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); | 2224 return GetCode(type, name); |
| 2143 } | 2225 } |
| 2144 | 2226 |
| 2145 | 2227 |
| 2146 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 2228 Handle<Code> CallStubCompiler::CompileMathFloorCall( |
| 2147 Handle<Object> object, | 2229 Handle<Object> object, |
| 2148 Handle<JSObject> holder, | 2230 Handle<JSObject> holder, |
| 2149 Handle<JSGlobalPropertyCell> cell, | 2231 Handle<Cell> cell, |
| 2150 Handle<JSFunction> function, | 2232 Handle<JSFunction> function, |
| 2151 Handle<String> name) { | 2233 Handle<String> name, |
| 2234 Code::StubType type) { |
| 2152 // TODO(872): implement this. | 2235 // TODO(872): implement this. |
| 2153 return Handle<Code>::null(); | 2236 return Handle<Code>::null(); |
| 2154 } | 2237 } |
| 2155 | 2238 |
| 2156 | 2239 |
| 2157 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 2240 Handle<Code> CallStubCompiler::CompileMathAbsCall( |
| 2158 Handle<Object> object, | 2241 Handle<Object> object, |
| 2159 Handle<JSObject> holder, | 2242 Handle<JSObject> holder, |
| 2160 Handle<JSGlobalPropertyCell> cell, | 2243 Handle<Cell> cell, |
| 2161 Handle<JSFunction> function, | 2244 Handle<JSFunction> function, |
| 2162 Handle<String> name) { | 2245 Handle<String> name, |
| 2246 Code::StubType type) { |
| 2163 // ----------- S t a t e ------------- | 2247 // ----------- S t a t e ------------- |
| 2164 // -- rcx : function name | 2248 // -- rcx : function name |
| 2165 // -- rsp[0] : return address | 2249 // -- rsp[0] : return address |
| 2166 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 2250 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
| 2167 // -- ... | 2251 // -- ... |
| 2168 // -- rsp[(argc + 1) * 8] : receiver | 2252 // -- rsp[(argc + 1) * 8] : receiver |
| 2169 // ----------------------------------- | 2253 // ----------------------------------- |
| 2170 | 2254 |
| 2171 // If the object is not a JSObject or we got an unexpected number of | 2255 // If the object is not a JSObject or we got an unexpected number of |
| 2172 // arguments, bail out to the regular call. | 2256 // arguments, bail out to the regular call. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2248 : CALL_AS_METHOD; | 2332 : CALL_AS_METHOD; |
| 2249 ParameterCount expected(function); | 2333 ParameterCount expected(function); |
| 2250 __ InvokeFunction(function, expected, arguments(), | 2334 __ InvokeFunction(function, expected, arguments(), |
| 2251 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2335 JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 2252 | 2336 |
| 2253 __ bind(&miss); | 2337 __ bind(&miss); |
| 2254 // rcx: function name. | 2338 // rcx: function name. |
| 2255 GenerateMissBranch(); | 2339 GenerateMissBranch(); |
| 2256 | 2340 |
| 2257 // Return the generated code. | 2341 // Return the generated code. |
| 2258 return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); | 2342 return GetCode(type, name); |
| 2259 } | 2343 } |
| 2260 | 2344 |
| 2261 | 2345 |
| 2262 Handle<Code> CallStubCompiler::CompileFastApiCall( | 2346 Handle<Code> CallStubCompiler::CompileFastApiCall( |
| 2263 const CallOptimization& optimization, | 2347 const CallOptimization& optimization, |
| 2264 Handle<Object> object, | 2348 Handle<Object> object, |
| 2265 Handle<JSObject> holder, | 2349 Handle<JSObject> holder, |
| 2266 Handle<JSGlobalPropertyCell> cell, | 2350 Handle<Cell> cell, |
| 2267 Handle<JSFunction> function, | 2351 Handle<JSFunction> function, |
| 2268 Handle<String> name) { | 2352 Handle<String> name) { |
| 2269 ASSERT(optimization.is_simple_api_call()); | 2353 ASSERT(optimization.is_simple_api_call()); |
| 2270 // Bail out if object is a global object as we don't want to | 2354 // Bail out if object is a global object as we don't want to |
| 2271 // repatch it to global receiver. | 2355 // repatch it to global receiver. |
| 2272 if (object->IsGlobalObject()) return Handle<Code>::null(); | 2356 if (object->IsGlobalObject()) return Handle<Code>::null(); |
| 2273 if (!cell.is_null()) return Handle<Code>::null(); | 2357 if (!cell.is_null()) return Handle<Code>::null(); |
| 2274 if (!object->IsJSObject()) return Handle<Code>::null(); | 2358 if (!object->IsJSObject()) return Handle<Code>::null(); |
| 2275 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2359 int depth = optimization.GetPrototypeDepthOfExpectedType( |
| 2276 Handle<JSObject>::cast(object), holder); | 2360 Handle<JSObject>::cast(object), holder); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2438 | 2522 |
| 2439 | 2523 |
| 2440 Handle<Code> CallStubCompiler::CompileCallConstant( | 2524 Handle<Code> CallStubCompiler::CompileCallConstant( |
| 2441 Handle<Object> object, | 2525 Handle<Object> object, |
| 2442 Handle<JSObject> holder, | 2526 Handle<JSObject> holder, |
| 2443 Handle<Name> name, | 2527 Handle<Name> name, |
| 2444 CheckType check, | 2528 CheckType check, |
| 2445 Handle<JSFunction> function) { | 2529 Handle<JSFunction> function) { |
| 2446 if (HasCustomCallGenerator(function)) { | 2530 if (HasCustomCallGenerator(function)) { |
| 2447 Handle<Code> code = CompileCustomCall(object, holder, | 2531 Handle<Code> code = CompileCustomCall(object, holder, |
| 2448 Handle<JSGlobalPropertyCell>::null(), | 2532 Handle<PropertyCell>::null(), |
| 2449 function, Handle<String>::cast(name)); | 2533 function, Handle<String>::cast(name), |
| 2534 Code::CONSTANT_FUNCTION); |
| 2450 // A null handle means bail out to the regular compiler code below. | 2535 // A null handle means bail out to the regular compiler code below. |
| 2451 if (!code.is_null()) return code; | 2536 if (!code.is_null()) return code; |
| 2452 } | 2537 } |
| 2453 | 2538 |
| 2454 Label success; | 2539 Label success; |
| 2455 | 2540 |
| 2456 CompileHandlerFrontend(object, holder, name, check, &success); | 2541 CompileHandlerFrontend(object, holder, name, check, &success); |
| 2457 __ bind(&success); | 2542 __ bind(&success); |
| 2458 CompileHandlerBackend(function); | 2543 CompileHandlerBackend(function); |
| 2459 | 2544 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2518 GenerateMissBranch(); | 2603 GenerateMissBranch(); |
| 2519 | 2604 |
| 2520 // Return the generated code. | 2605 // Return the generated code. |
| 2521 return GetCode(Code::INTERCEPTOR, name); | 2606 return GetCode(Code::INTERCEPTOR, name); |
| 2522 } | 2607 } |
| 2523 | 2608 |
| 2524 | 2609 |
| 2525 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2610 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2526 Handle<JSObject> object, | 2611 Handle<JSObject> object, |
| 2527 Handle<GlobalObject> holder, | 2612 Handle<GlobalObject> holder, |
| 2528 Handle<JSGlobalPropertyCell> cell, | 2613 Handle<PropertyCell> cell, |
| 2529 Handle<JSFunction> function, | 2614 Handle<JSFunction> function, |
| 2530 Handle<Name> name) { | 2615 Handle<Name> name) { |
| 2531 // ----------- S t a t e ------------- | 2616 // ----------- S t a t e ------------- |
| 2532 // rcx : function name | 2617 // rcx : function name |
| 2533 // rsp[0] : return address | 2618 // rsp[0] : return address |
| 2534 // rsp[8] : argument argc | 2619 // rsp[8] : argument argc |
| 2535 // rsp[16] : argument argc - 1 | 2620 // rsp[16] : argument argc - 1 |
| 2536 // ... | 2621 // ... |
| 2537 // rsp[argc * 8] : argument 1 | 2622 // rsp[argc * 8] : argument 1 |
| 2538 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2623 // rsp[(argc + 1) * 8] : argument 0 = receiver |
| 2539 // ----------------------------------- | 2624 // ----------------------------------- |
| 2540 | 2625 |
| 2541 if (HasCustomCallGenerator(function)) { | 2626 if (HasCustomCallGenerator(function)) { |
| 2542 Handle<Code> code = CompileCustomCall( | 2627 Handle<Code> code = CompileCustomCall( |
| 2543 object, holder, cell, function, Handle<String>::cast(name)); | 2628 object, holder, cell, function, Handle<String>::cast(name), |
| 2629 Code::NORMAL); |
| 2544 // A null handle means bail out to the regular compiler code below. | 2630 // A null handle means bail out to the regular compiler code below. |
| 2545 if (!code.is_null()) return code; | 2631 if (!code.is_null()) return code; |
| 2546 } | 2632 } |
| 2547 | 2633 |
| 2548 Label miss; | 2634 Label miss; |
| 2549 GenerateNameCheck(name, &miss); | 2635 GenerateNameCheck(name, &miss); |
| 2550 | 2636 |
| 2551 // Get the number of arguments. | 2637 // Get the number of arguments. |
| 2552 const int argc = arguments().immediate(); | 2638 const int argc = arguments().immediate(); |
| 2553 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2639 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2701 __ bind(&miss); | 2787 __ bind(&miss); |
| 2702 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2788 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2703 | 2789 |
| 2704 // Return the generated code. | 2790 // Return the generated code. |
| 2705 return GetICCode(kind(), Code::INTERCEPTOR, name); | 2791 return GetICCode(kind(), Code::INTERCEPTOR, name); |
| 2706 } | 2792 } |
| 2707 | 2793 |
| 2708 | 2794 |
| 2709 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 2795 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
| 2710 Handle<GlobalObject> object, | 2796 Handle<GlobalObject> object, |
| 2711 Handle<JSGlobalPropertyCell> cell, | 2797 Handle<PropertyCell> cell, |
| 2712 Handle<Name> name) { | 2798 Handle<Name> name) { |
| 2713 Label miss; | 2799 Label miss; |
| 2714 | 2800 |
| 2715 // Check that the map of the global has not changed. | 2801 // Check that the map of the global has not changed. |
| 2716 __ Cmp(FieldOperand(receiver(), HeapObject::kMapOffset), | 2802 __ Cmp(FieldOperand(receiver(), HeapObject::kMapOffset), |
| 2717 Handle<Map>(object->map())); | 2803 Handle<Map>(object->map())); |
| 2718 __ j(not_equal, &miss); | 2804 __ j(not_equal, &miss); |
| 2719 | 2805 |
| 2720 // Compute the cell operand to use. | 2806 // Compute the cell operand to use. |
| 2721 __ Move(scratch1(), cell); | 2807 __ Move(scratch1(), cell); |
| 2722 Operand cell_operand = | 2808 Operand cell_operand = |
| 2723 FieldOperand(scratch1(), JSGlobalPropertyCell::kValueOffset); | 2809 FieldOperand(scratch1(), PropertyCell::kValueOffset); |
| 2724 | 2810 |
| 2725 // Check that the value in the cell is not the hole. If it is, this | 2811 // Check that the value in the cell is not the hole. If it is, this |
| 2726 // cell could have been deleted and reintroducing the global needs | 2812 // cell could have been deleted and reintroducing the global needs |
| 2727 // to update the property details in the property dictionary of the | 2813 // to update the property details in the property dictionary of the |
| 2728 // global object. We bail out to the runtime system to do that. | 2814 // global object. We bail out to the runtime system to do that. |
| 2729 __ CompareRoot(cell_operand, Heap::kTheHoleValueRootIndex); | 2815 __ CompareRoot(cell_operand, Heap::kTheHoleValueRootIndex); |
| 2730 __ j(equal, &miss); | 2816 __ j(equal, &miss); |
| 2731 | 2817 |
| 2732 // Store the value in the cell. | 2818 // Store the value in the cell. |
| 2733 __ movq(cell_operand, value()); | 2819 __ movq(cell_operand, value()); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2881 } | 2967 } |
| 2882 | 2968 |
| 2883 | 2969 |
| 2884 #undef __ | 2970 #undef __ |
| 2885 #define __ ACCESS_MASM(masm()) | 2971 #define __ ACCESS_MASM(masm()) |
| 2886 | 2972 |
| 2887 | 2973 |
| 2888 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 2974 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
| 2889 Handle<JSObject> object, | 2975 Handle<JSObject> object, |
| 2890 Handle<GlobalObject> global, | 2976 Handle<GlobalObject> global, |
| 2891 Handle<JSGlobalPropertyCell> cell, | 2977 Handle<PropertyCell> cell, |
| 2892 Handle<Name> name, | 2978 Handle<Name> name, |
| 2893 bool is_dont_delete) { | 2979 bool is_dont_delete) { |
| 2894 Label success, miss; | 2980 Label success, miss; |
| 2895 // TODO(verwaest): Directly store to rax. Currently we cannot do this, since | 2981 // TODO(verwaest): Directly store to rax. Currently we cannot do this, since |
| 2896 // rax is used as receiver(), which we would otherwise clobber before a | 2982 // rax is used as receiver(), which we would otherwise clobber before a |
| 2897 // potential miss. | 2983 // potential miss. |
| 2898 | 2984 |
| 2899 __ CheckMap(receiver(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK); | 2985 __ CheckMap(receiver(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK); |
| 2900 HandlerFrontendHeader( | 2986 HandlerFrontendHeader( |
| 2901 object, receiver(), Handle<JSObject>::cast(global), name, &miss); | 2987 object, receiver(), Handle<JSObject>::cast(global), name, &miss); |
| 2902 | 2988 |
| 2903 // Get the value from the cell. | 2989 // Get the value from the cell. |
| 2904 __ Move(rbx, cell); | 2990 __ Move(rbx, cell); |
| 2905 __ movq(rbx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset)); | 2991 __ movq(rbx, FieldOperand(rbx, PropertyCell::kValueOffset)); |
| 2906 | 2992 |
| 2907 // Check for deleted property if property can actually be deleted. | 2993 // Check for deleted property if property can actually be deleted. |
| 2908 if (!is_dont_delete) { | 2994 if (!is_dont_delete) { |
| 2909 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 2995 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); |
| 2910 __ j(equal, &miss); | 2996 __ j(equal, &miss); |
| 2911 } else if (FLAG_debug_code) { | 2997 } else if (FLAG_debug_code) { |
| 2912 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 2998 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); |
| 2913 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 2999 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
| 2914 } | 3000 } |
| 2915 | 3001 |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3486 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3572 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
| 3487 } | 3573 } |
| 3488 } | 3574 } |
| 3489 | 3575 |
| 3490 | 3576 |
| 3491 #undef __ | 3577 #undef __ |
| 3492 | 3578 |
| 3493 } } // namespace v8::internal | 3579 } } // namespace v8::internal |
| 3494 | 3580 |
| 3495 #endif // V8_TARGET_ARCH_X64 | 3581 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |