| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 bool restore_context) { | 840 bool restore_context) { |
| 841 // ----------- S t a t e ------------- | 841 // ----------- S t a t e ------------- |
| 842 // -- sp[0] - sp[48] : FunctionCallbackInfo, including | 842 // -- sp[0] - sp[48] : FunctionCallbackInfo, including |
| 843 // holder (set by CheckPrototypes) | 843 // holder (set by CheckPrototypes) |
| 844 // -- sp[56] : last JS argument | 844 // -- sp[56] : last JS argument |
| 845 // -- ... | 845 // -- ... |
| 846 // -- sp[(argc + 6) * 8] : first JS argument | 846 // -- sp[(argc + 6) * 8] : first JS argument |
| 847 // -- sp[(argc + 7) * 8] : receiver | 847 // -- sp[(argc + 7) * 8] : receiver |
| 848 // ----------------------------------- | 848 // ----------------------------------- |
| 849 typedef FunctionCallbackArguments FCA; | 849 typedef FunctionCallbackArguments FCA; |
| 850 const int kArgs = kFastApiCallArguments; | |
| 851 // Save calling context. | 850 // Save calling context. |
| 852 __ Poke(cp, (kArgs - 1 + FCA::kContextSaveIndex) * kPointerSize); | 851 __ Poke(cp, FCA::kContextSaveIndex * kPointerSize); |
| 853 // Get the function and setup the context. | 852 // Get the function and setup the context. |
| 854 Handle<JSFunction> function = optimization.constant_function(); | 853 Handle<JSFunction> function = optimization.constant_function(); |
| 855 Register function_reg = x5; | 854 Register function_reg = x5; |
| 856 __ LoadHeapObject(function_reg, function); | 855 __ LoadHeapObject(function_reg, function); |
| 857 __ Ldr(cp, FieldMemOperand(function_reg, JSFunction::kContextOffset)); | 856 __ Ldr(cp, FieldMemOperand(function_reg, JSFunction::kContextOffset)); |
| 858 __ Poke(function_reg, (kArgs - 1 + FCA::kCalleeIndex) * kPointerSize); | 857 __ Poke(function_reg, FCA::kCalleeIndex * kPointerSize); |
| 859 | 858 |
| 860 // Construct the FunctionCallbackInfo. | 859 // Construct the FunctionCallbackInfo. |
| 861 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 860 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
| 862 Handle<Object> call_data(api_call_info->data(), masm->isolate()); | 861 Handle<Object> call_data(api_call_info->data(), masm->isolate()); |
| 863 Register call_data_reg = x6; | 862 Register call_data_reg = x6; |
| 864 if (masm->isolate()->heap()->InNewSpace(*call_data)) { | 863 if (masm->isolate()->heap()->InNewSpace(*call_data)) { |
| 865 __ Mov(x0, Operand(api_call_info)); | 864 __ Mov(x0, Operand(api_call_info)); |
| 866 __ Ldr(call_data_reg, FieldMemOperand(x0, CallHandlerInfo::kDataOffset)); | 865 __ Ldr(call_data_reg, FieldMemOperand(x0, CallHandlerInfo::kDataOffset)); |
| 867 } else { | 866 } else { |
| 868 __ Mov(call_data_reg, Operand(call_data)); | 867 __ Mov(call_data_reg, Operand(call_data)); |
| 869 } | 868 } |
| 870 // Store call data. | 869 // Store call data. |
| 871 __ Poke(call_data_reg, (kArgs - 1 + FCA::kDataIndex) * kPointerSize); | 870 __ Poke(call_data_reg, FCA::kDataIndex * kPointerSize); |
| 872 // Store isolate. | 871 // Store isolate. |
| 873 Register isolate_reg = x7; | 872 Register isolate_reg = x7; |
| 874 __ Mov(isolate_reg, | 873 __ Mov(isolate_reg, |
| 875 Operand(ExternalReference::isolate_address(masm->isolate()))); | 874 Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 876 __ Poke(isolate_reg, (kArgs - 1 + FCA::kIsolateIndex) * kPointerSize); | 875 __ Poke(isolate_reg, FCA::kIsolateIndex * kPointerSize); |
| 877 // Store ReturnValue default and ReturnValue. | 876 // Store ReturnValue default and ReturnValue. |
| 878 Register undefined_reg = x8; | 877 Register undefined_reg = x8; |
| 879 __ LoadRoot(undefined_reg, Heap::kUndefinedValueRootIndex); | 878 __ LoadRoot(undefined_reg, Heap::kUndefinedValueRootIndex); |
| 880 __ Poke(undefined_reg, (kArgs - 1 + FCA::kReturnValueOffset) * kPointerSize); | 879 // TODO(all): These are adjacent. Once things settle down, use PokePair. |
| 881 __ Poke(undefined_reg, | 880 __ Poke(undefined_reg, FCA::kReturnValueOffset * kPointerSize); |
| 882 (kArgs - 1 + FCA::kReturnValueDefaultValueIndex) * kPointerSize); | 881 __ Poke(undefined_reg, FCA::kReturnValueDefaultValueIndex * kPointerSize); |
| 883 | 882 |
| 884 Register implicit_args = x2; | 883 Register implicit_args = x2; |
| 885 __ Add(implicit_args, masm->StackPointer(), (kArgs - 1) * kPointerSize); | 884 __ Mov(implicit_args, masm->StackPointer()); |
| 886 | 885 |
| 887 FrameScope frame_scope(masm, StackFrame::MANUAL); | 886 FrameScope frame_scope(masm, StackFrame::MANUAL); |
| 888 // Allocate the v8::Arguments structure inside the ExitFrame since it's not | 887 // Allocate the v8::Arguments structure inside the ExitFrame since it's not |
| 889 // controlled by GC. | 888 // controlled by GC. |
| 890 const int kApiArgsStackSpace = 4; | 889 const int kApiArgsStackSpace = 4; |
| 891 __ EnterExitFrame( | 890 __ EnterExitFrame( |
| 892 false, | 891 false, |
| 893 x3, | 892 x3, |
| 894 kApiArgsStackSpace + MacroAssembler::kCallApiFunctionSpillSpace); | 893 kApiArgsStackSpace + MacroAssembler::kCallApiFunctionSpillSpace); |
| 895 | 894 |
| 896 // Arguments structure is after the return address. | 895 // Arguments structure is after the return address. |
| 896 // args = FunctionCallbackInfo& |
| 897 Register args = x0; | 897 Register args = x0; |
| 898 __ Add(args, masm->StackPointer(), kPointerSize); | 898 __ Add(args, masm->StackPointer(), kPointerSize); |
| 899 | 899 |
| 900 // v8::Arguments::implicit_args_ | 900 // FunctionCallbackInfo::implicit_args_ |
| 901 __ Str(implicit_args, MemOperand(args, 0 * kPointerSize)); | 901 __ Str(implicit_args, MemOperand(args, 0 * kPointerSize)); |
| 902 // v8::Arguments::values_ | 902 // FunctionCallbackInfo::values_ |
| 903 __ Add(x3, implicit_args, argc * kPointerSize); | 903 __ Add(x3, implicit_args, (kFastApiCallArguments - 1 + argc) * kPointerSize); |
| 904 __ Str(x3, MemOperand(args, 1 * kPointerSize)); | 904 __ Str(x3, MemOperand(args, 1 * kPointerSize)); |
| 905 // v8::Arguments::length_ = argc | 905 // FunctionCallbackInfo::length_ = argc |
| 906 __ Mov(x3, argc); | 906 __ Mov(x3, argc); |
| 907 __ Str(x3, MemOperand(args, 2 * kPointerSize)); | 907 __ Str(x3, MemOperand(args, 2 * kPointerSize)); |
| 908 // v8::Arguments::is_construct_call = 0 | 908 // FunctionCallbackInfo::is_construct_call = 0 |
| 909 __ Mov(x3, 0); | 909 __ Str(xzr, MemOperand(args, 3 * kPointerSize)); |
| 910 __ Str(x3, MemOperand(args, 3 * kPointerSize)); | |
| 911 | 910 |
| 912 // After the call to the API function we need to free memory used for: | 911 // After the call to the API function we need to free memory used for: |
| 913 // - JS arguments | 912 // - JS arguments |
| 914 // - the receiver | 913 // - the receiver |
| 915 // - the space allocated by ReserveSpaceForFastApiCall. | 914 // - the space allocated by ReserveSpaceForFastApiCall. |
| 916 // | 915 // |
| 917 // The memory allocated for v8::Arguments structure will be freed when we'll | 916 // The memory allocated for v8::Arguments structure will be freed when we'll |
| 918 // leave the ExitFrame. | 917 // leave the ExitFrame. |
| 919 const int kStackUnwindSpace = argc + kArgs + 1; | 918 const int kStackUnwindSpace = argc + kFastApiCallArguments + 1; |
| 920 | 919 |
| 921 Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 920 Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
| 922 ApiFunction fun(function_address); | 921 ApiFunction fun(function_address); |
| 923 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; | 922 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; |
| 924 ExternalReference ref = ExternalReference(&fun, type, masm->isolate()); | 923 ExternalReference ref = ExternalReference(&fun, type, masm->isolate()); |
| 925 | 924 |
| 926 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); | 925 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); |
| 927 ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL; | 926 ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL; |
| 928 ApiFunction thunk_fun(thunk_address); | 927 ApiFunction thunk_fun(thunk_address); |
| 929 ExternalReference thunk_ref = | 928 ExternalReference thunk_ref = |
| 930 ExternalReference(&thunk_fun, thunk_type, masm->isolate()); | 929 ExternalReference(&thunk_fun, thunk_type, masm->isolate()); |
| 931 | 930 |
| 932 AllowExternalCallThatCantCauseGC scope(masm); | 931 AllowExternalCallThatCantCauseGC scope(masm); |
| 933 MemOperand context_restore_operand( | 932 MemOperand context_restore_operand( |
| 934 fp, (kArgs + 1 + FCA::kContextSaveIndex) * kPointerSize); | 933 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); |
| 935 MemOperand return_value_operand( | 934 MemOperand return_value_operand( |
| 936 fp, (kArgs + 1 + FCA::kReturnValueOffset) * kPointerSize); | 935 fp, (2 + FCA::kReturnValueOffset) * kPointerSize); |
| 936 |
| 937 // CallApiFunctionAndReturn can spill registers inside the exit frame, | 937 // CallApiFunctionAndReturn can spill registers inside the exit frame, |
| 938 // after the return address and the v8::Arguments structure. | 938 // after the return address and the v8::Arguments structure. |
| 939 const int spill_offset = 1 + kApiArgsStackSpace; | 939 const int spill_offset = 1 + kApiArgsStackSpace; |
| 940 __ CallApiFunctionAndReturn(ref, | 940 __ CallApiFunctionAndReturn(ref, |
| 941 function_address, | 941 function_address, |
| 942 thunk_ref, | 942 thunk_ref, |
| 943 x1, | 943 x1, |
| 944 kStackUnwindSpace, | 944 kStackUnwindSpace, |
| 945 spill_offset, | 945 spill_offset, |
| 946 return_value_operand, | 946 return_value_operand, |
| 947 restore_context ? | 947 restore_context ? |
| 948 &context_restore_operand : NULL); | 948 &context_restore_operand : NULL); |
| 949 } | 949 } |
| 950 | 950 |
| 951 | 951 |
| 952 // Generate call to api function. | 952 // Generate call to api function. |
| 953 static void GenerateFastApiCall(MacroAssembler* masm, | 953 static void GenerateFastApiCall(MacroAssembler* masm, |
| 954 const CallOptimization& optimization, | 954 const CallOptimization& optimization, |
| 955 Register receiver, | 955 Register receiver, |
| 956 Register scratch, | 956 Register scratch, |
| 957 int argc, | 957 int argc, |
| 958 Register* values) { | 958 Register* values) { |
| 959 ASSERT(optimization.is_simple_api_call()); | 959 ASSERT(optimization.is_simple_api_call()); |
| 960 ASSERT(!AreAliased(receiver, scratch)); | 960 ASSERT(!AreAliased(receiver, scratch)); |
| 961 | 961 |
| 962 typedef FunctionCallbackArguments FCA; |
| 962 const int stack_space = kFastApiCallArguments + argc + 1; | 963 const int stack_space = kFastApiCallArguments + argc + 1; |
| 963 const int kHolderIndex = kFastApiCallArguments + | |
| 964 FunctionCallbackArguments::kHolderIndex - 1; | |
| 965 // Assign stack space for the call arguments. | 964 // Assign stack space for the call arguments. |
| 966 __ Claim(stack_space); | 965 __ Claim(stack_space); |
| 967 // Write holder to stack frame. | 966 // Write holder to stack frame. |
| 968 __ Poke(receiver, kHolderIndex * kPointerSize); | 967 __ Poke(receiver, FCA::kHolderIndex * kPointerSize); |
| 969 // Write receiver to stack frame. | 968 // Write receiver to stack frame. |
| 970 int index = stack_space - 1; | 969 int index = stack_space - 1; |
| 971 __ Poke(receiver, index * kPointerSize); | 970 __ Poke(receiver, index * kPointerSize); |
| 972 // Write the arguments to stack frame. | 971 // Write the arguments to stack frame. |
| 973 for (int i = 0; i < argc; i++) { | 972 for (int i = 0; i < argc; i++) { |
| 974 // TODO(jbramley): This is broken, but it is broken on ARM too. | 973 // TODO(jbramley): This is broken, but it is broken on ARM too. |
| 975 ASSERT(!AreAliased(receiver, scratch, values[i])); | 974 ASSERT(!AreAliased(receiver, scratch, values[i])); |
| 976 __ Poke(receiver, index-- * kPointerSize); | 975 __ Poke(receiver, index-- * kPointerSize); |
| 977 } | 976 } |
| 978 | 977 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1187 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
| 1189 Register object_reg, | 1188 Register object_reg, |
| 1190 Handle<JSObject> holder, | 1189 Handle<JSObject> holder, |
| 1191 Register holder_reg, | 1190 Register holder_reg, |
| 1192 Register scratch1, | 1191 Register scratch1, |
| 1193 Register scratch2, | 1192 Register scratch2, |
| 1194 Handle<Name> name, | 1193 Handle<Name> name, |
| 1195 int save_at_depth, | 1194 int save_at_depth, |
| 1196 Label* miss, | 1195 Label* miss, |
| 1197 PrototypeCheckType check) { | 1196 PrototypeCheckType check) { |
| 1198 const int kHolderIndex = kFastApiCallArguments + | |
| 1199 FunctionCallbackArguments::kHolderIndex - 1; | |
| 1200 // Make sure that the type feedback oracle harvests the receiver map. | 1197 // Make sure that the type feedback oracle harvests the receiver map. |
| 1201 // TODO(svenpanne) Remove this hack when all ICs are reworked. | 1198 // TODO(svenpanne) Remove this hack when all ICs are reworked. |
| 1202 __ Mov(scratch1, Operand(Handle<Map>(object->map()))); | 1199 __ Mov(scratch1, Operand(Handle<Map>(object->map()))); |
| 1203 | 1200 |
| 1204 Handle<JSObject> first = object; | 1201 Handle<JSObject> first = object; |
| 1205 | 1202 |
| 1206 // object_reg and holder_reg registers can alias. | 1203 // object_reg and holder_reg registers can alias. |
| 1207 ASSERT(!AreAliased(object_reg, scratch1, scratch2)); | 1204 ASSERT(!AreAliased(object_reg, scratch1, scratch2)); |
| 1208 ASSERT(!AreAliased(holder_reg, scratch1, scratch2)); | 1205 ASSERT(!AreAliased(holder_reg, scratch1, scratch2)); |
| 1209 | 1206 |
| 1210 // Keep track of the current object in register reg. | 1207 // Keep track of the current object in register reg. |
| 1211 Register reg = object_reg; | 1208 Register reg = object_reg; |
| 1212 int depth = 0; | 1209 int depth = 0; |
| 1213 | 1210 |
| 1211 typedef FunctionCallbackArguments FCA; |
| 1214 if (save_at_depth == depth) { | 1212 if (save_at_depth == depth) { |
| 1215 __ Poke(reg, kHolderIndex * kPointerSize); | 1213 __ Poke(reg, FCA::kHolderIndex * kPointerSize); |
| 1216 } | 1214 } |
| 1217 | 1215 |
| 1218 // Check the maps in the prototype chain. | 1216 // Check the maps in the prototype chain. |
| 1219 // Traverse the prototype chain from the object and do map checks. | 1217 // Traverse the prototype chain from the object and do map checks. |
| 1220 Handle<JSObject> current = object; | 1218 Handle<JSObject> current = object; |
| 1221 while (!current.is_identical_to(holder)) { | 1219 while (!current.is_identical_to(holder)) { |
| 1222 ++depth; | 1220 ++depth; |
| 1223 | 1221 |
| 1224 // Only global objects and objects that do not require access | 1222 // Only global objects and objects that do not require access |
| 1225 // checks are allowed in stubs. | 1223 // checks are allowed in stubs. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1264 // The prototype is in new space; we cannot store a reference to it | 1262 // The prototype is in new space; we cannot store a reference to it |
| 1265 // in the code. Load it from the map. | 1263 // in the code. Load it from the map. |
| 1266 __ Ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); | 1264 __ Ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); |
| 1267 } else { | 1265 } else { |
| 1268 // The prototype is in old space; load it directly. | 1266 // The prototype is in old space; load it directly. |
| 1269 __ Mov(reg, Operand(prototype)); | 1267 __ Mov(reg, Operand(prototype)); |
| 1270 } | 1268 } |
| 1271 } | 1269 } |
| 1272 | 1270 |
| 1273 if (save_at_depth == depth) { | 1271 if (save_at_depth == depth) { |
| 1274 __ Poke(reg, kHolderIndex * kPointerSize); | 1272 __ Poke(reg, FCA::kHolderIndex * kPointerSize); |
| 1275 } | 1273 } |
| 1276 | 1274 |
| 1277 // Go to the next object in the prototype chain. | 1275 // Go to the next object in the prototype chain. |
| 1278 current = prototype; | 1276 current = prototype; |
| 1279 } | 1277 } |
| 1280 | 1278 |
| 1281 // Log the check depth. | 1279 // Log the check depth. |
| 1282 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 1280 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1283 | 1281 |
| 1284 // Check the holder map. | 1282 // Check the holder map. |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1431 | 1429 |
| 1432 | 1430 |
| 1433 void BaseLoadStubCompiler::GenerateLoadCallback( | 1431 void BaseLoadStubCompiler::GenerateLoadCallback( |
| 1434 Register reg, | 1432 Register reg, |
| 1435 Handle<ExecutableAccessorInfo> callback) { | 1433 Handle<ExecutableAccessorInfo> callback) { |
| 1436 ASSERT(!AreAliased(scratch2(), scratch3(), scratch4(), reg)); | 1434 ASSERT(!AreAliased(scratch2(), scratch3(), scratch4(), reg)); |
| 1437 | 1435 |
| 1438 // Build ExecutableAccessorInfo::args_ list on the stack and push property | 1436 // Build ExecutableAccessorInfo::args_ list on the stack and push property |
| 1439 // name below the exit frame to make GC aware of them and store pointers to | 1437 // name below the exit frame to make GC aware of them and store pointers to |
| 1440 // them. | 1438 // them. |
| 1441 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 0); | 1439 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); |
| 1442 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == -1); | 1440 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); |
| 1443 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == -2); | 1441 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); |
| 1444 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == -3); | 1442 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); |
| 1445 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == -4); | 1443 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); |
| 1446 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == -5); | 1444 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); |
| 1445 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); |
| 1447 | 1446 |
| 1448 __ Push(receiver()); | 1447 __ Push(receiver()); |
| 1449 Register args_addr = scratch2(); | |
| 1450 __ Mov(args_addr, __ StackPointer()); | |
| 1451 | 1448 |
| 1452 if (heap()->InNewSpace(callback->data())) { | 1449 if (heap()->InNewSpace(callback->data())) { |
| 1453 __ Mov(scratch3(), Operand(callback)); | 1450 __ Mov(scratch3(), Operand(callback)); |
| 1454 __ Ldr(scratch3(), FieldMemOperand(scratch3(), | 1451 __ Ldr(scratch3(), FieldMemOperand(scratch3(), |
| 1455 ExecutableAccessorInfo::kDataOffset)); | 1452 ExecutableAccessorInfo::kDataOffset)); |
| 1456 } else { | 1453 } else { |
| 1457 __ Mov(scratch3(), Operand(Handle<Object>(callback->data(), isolate()))); | 1454 __ Mov(scratch3(), Operand(Handle<Object>(callback->data(), isolate()))); |
| 1458 } | 1455 } |
| 1459 // TODO(jbramley): Find another scratch register and combine the pushes | 1456 // TODO(jbramley): Find another scratch register and combine the pushes |
| 1460 // together. Can we use scratch1() here? | 1457 // together. Can we use scratch1() here? |
| 1461 // Push: | |
| 1462 // - callback data | |
| 1463 // - undefined | |
| 1464 // - undefined | |
| 1465 // - isolate | |
| 1466 // - reg | |
| 1467 // - name | |
| 1468 __ LoadRoot(scratch4(), Heap::kUndefinedValueRootIndex); | 1458 __ LoadRoot(scratch4(), Heap::kUndefinedValueRootIndex); |
| 1469 __ Push(scratch3(), scratch4()); | 1459 __ Push(scratch3(), scratch4()); |
| 1470 __ Mov(scratch3(), Operand(ExternalReference::isolate_address(isolate()))); | 1460 __ Mov(scratch3(), Operand(ExternalReference::isolate_address(isolate()))); |
| 1471 __ Push(scratch4(), scratch3(), reg, name()); | 1461 __ Push(scratch4(), scratch3(), reg, name()); |
| 1472 | 1462 |
| 1463 Register args_addr = scratch2(); |
| 1464 __ Add(args_addr, __ StackPointer(), kPointerSize); |
| 1465 |
| 1466 // Stack at this point: |
| 1467 // sp[40] callback data |
| 1468 // sp[32] undefined |
| 1469 // sp[24] undefined |
| 1470 // sp[16] isolate |
| 1471 // args_addr -> sp[8] reg |
| 1472 // sp[0] name |
| 1473 |
| 1473 // Pass the Handle<Name> of the property name to the runtime. | 1474 // Pass the Handle<Name> of the property name to the runtime. |
| 1474 __ Mov(x0, __ StackPointer()); | 1475 __ Mov(x0, __ StackPointer()); |
| 1475 | 1476 |
| 1476 FrameScope frame_scope(masm(), StackFrame::MANUAL); | 1477 FrameScope frame_scope(masm(), StackFrame::MANUAL); |
| 1477 const int kApiStackSpace = 1; | 1478 const int kApiStackSpace = 1; |
| 1478 __ EnterExitFrame(false, scratch4(), | 1479 __ EnterExitFrame(false, scratch4(), |
| 1479 kApiStackSpace + MacroAssembler::kCallApiFunctionSpillSpace); | 1480 kApiStackSpace + MacroAssembler::kCallApiFunctionSpillSpace); |
| 1480 | 1481 |
| 1481 // Create ExecutableAccessorInfo instance on the stack above the exit frame | 1482 // Create PropertyAccessorInfo instance on the stack above the exit frame |
| 1482 // before the return address. ExecutableAccessorInfo has only one field: the | 1483 // (before the return address) with args_addr as the data. |
| 1483 // address of args_. | |
| 1484 __ Poke(args_addr, 1 * kPointerSize); | 1484 __ Poke(args_addr, 1 * kPointerSize); |
| 1485 | 1485 |
| 1486 // Get the address of ExecutableAccessorInfo instance and pass it to the | 1486 // Get the address of ExecutableAccessorInfo instance and pass it to the |
| 1487 // runtime. | 1487 // runtime. |
| 1488 __ Add(x1, __ StackPointer(), 1 * kPointerSize); | 1488 __ Add(x1, __ StackPointer(), 1 * kPointerSize); |
| 1489 | 1489 |
| 1490 // CallApiFunctionAndReturn can spill registers inside the exit frame, after | 1490 // CallApiFunctionAndReturn can spill registers inside the exit frame, after |
| 1491 // the return address and the ExecutableAccessorInfo instance. | 1491 // the return address and the ExecutableAccessorInfo instance. |
| 1492 const int spill_offset = 1 + kApiStackSpace; | 1492 const int spill_offset = 1 + kApiStackSpace; |
| 1493 | 1493 |
| (...skipping 1771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3265 | 3265 |
| 3266 // Miss case, call the runtime. | 3266 // Miss case, call the runtime. |
| 3267 __ Bind(&miss_force_generic); | 3267 __ Bind(&miss_force_generic); |
| 3268 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); | 3268 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); |
| 3269 } | 3269 } |
| 3270 | 3270 |
| 3271 | 3271 |
| 3272 } } // namespace v8::internal | 3272 } } // namespace v8::internal |
| 3273 | 3273 |
| 3274 #endif // V8_TARGET_ARCH_A64 | 3274 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |