| 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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 | 367 |
| 368 | 368 |
| 369 // Generate code to load the length from a string object and return the length. | 369 // Generate code to load the length from a string object and return the length. |
| 370 // If the receiver object is not a string or a wrapped string object the | 370 // If the receiver object is not a string or a wrapped string object the |
| 371 // execution continues at the miss label. The register containing the | 371 // execution continues at the miss label. The register containing the |
| 372 // receiver is potentially clobbered. | 372 // receiver is potentially clobbered. |
| 373 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, | 373 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, |
| 374 Register receiver, | 374 Register receiver, |
| 375 Register scratch1, | 375 Register scratch1, |
| 376 Register scratch2, | 376 Register scratch2, |
| 377 Label* miss) { | 377 Label* miss, |
| 378 bool support_wrappers) { |
| 378 Label check_wrapper; | 379 Label check_wrapper; |
| 379 | 380 |
| 380 // Check if the object is a string leaving the instance type in the | 381 // Check if the object is a string leaving the instance type in the |
| 381 // scratch1 register. | 382 // scratch1 register. |
| 382 GenerateStringCheck(masm, receiver, scratch1, scratch2, miss, &check_wrapper); | 383 GenerateStringCheck(masm, receiver, scratch1, scratch2, miss, |
| 384 support_wrappers ? &check_wrapper : miss); |
| 383 | 385 |
| 384 // Load length directly from the string. | 386 // Load length directly from the string. |
| 385 __ Ret(USE_DELAY_SLOT); | 387 __ Ret(USE_DELAY_SLOT); |
| 386 __ lw(v0, FieldMemOperand(receiver, String::kLengthOffset)); | 388 __ lw(v0, FieldMemOperand(receiver, String::kLengthOffset)); |
| 387 | 389 |
| 388 // Check if the object is a JSValue wrapper. | 390 if (support_wrappers) { |
| 389 __ bind(&check_wrapper); | 391 // Check if the object is a JSValue wrapper. |
| 390 __ Branch(miss, ne, scratch1, Operand(JS_VALUE_TYPE)); | 392 __ bind(&check_wrapper); |
| 393 __ Branch(miss, ne, scratch1, Operand(JS_VALUE_TYPE)); |
| 391 | 394 |
| 392 // Unwrap the value and check if the wrapped value is a string. | 395 // Unwrap the value and check if the wrapped value is a string. |
| 393 __ lw(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset)); | 396 __ lw(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset)); |
| 394 GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss); | 397 GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss); |
| 395 __ Ret(USE_DELAY_SLOT); | 398 __ Ret(USE_DELAY_SLOT); |
| 396 __ lw(v0, FieldMemOperand(scratch1, String::kLengthOffset)); | 399 __ lw(v0, FieldMemOperand(scratch1, String::kLengthOffset)); |
| 400 } |
| 397 } | 401 } |
| 398 | 402 |
| 399 | 403 |
| 400 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, | 404 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, |
| 401 Register receiver, | 405 Register receiver, |
| 402 Register scratch1, | 406 Register scratch1, |
| 403 Register scratch2, | 407 Register scratch2, |
| 404 Label* miss_label) { | 408 Label* miss_label) { |
| 405 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); | 409 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); |
| 406 __ Ret(USE_DELAY_SLOT); | 410 __ Ret(USE_DELAY_SLOT); |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 | 826 |
| 823 | 827 |
| 824 // Undoes the effects of ReserveSpaceForFastApiCall. | 828 // Undoes the effects of ReserveSpaceForFastApiCall. |
| 825 static void FreeSpaceForFastApiCall(MacroAssembler* masm) { | 829 static void FreeSpaceForFastApiCall(MacroAssembler* masm) { |
| 826 __ Drop(kFastApiCallArguments); | 830 __ Drop(kFastApiCallArguments); |
| 827 } | 831 } |
| 828 | 832 |
| 829 | 833 |
| 830 static void GenerateFastApiDirectCall(MacroAssembler* masm, | 834 static void GenerateFastApiDirectCall(MacroAssembler* masm, |
| 831 const CallOptimization& optimization, | 835 const CallOptimization& optimization, |
| 832 int argc, | 836 int argc) { |
| 833 bool restore_context) { | |
| 834 // ----------- S t a t e ------------- | 837 // ----------- S t a t e ------------- |
| 835 // -- sp[0] : context | 838 // -- sp[0] : holder (set by CheckPrototypes) |
| 836 // -- sp[4] : holder (set by CheckPrototypes) | 839 // -- sp[4] : callee JS function |
| 837 // -- sp[8] : callee JS function | 840 // -- sp[8] : call data |
| 838 // -- sp[12] : call data | 841 // -- sp[12] : isolate |
| 839 // -- sp[16] : isolate | 842 // -- sp[16] : ReturnValue default value |
| 840 // -- sp[20] : ReturnValue default value | 843 // -- sp[20] : ReturnValue |
| 841 // -- sp[24] : ReturnValue | 844 // -- sp[24] : last JS argument |
| 842 // -- sp[28] : last JS argument | |
| 843 // -- ... | 845 // -- ... |
| 844 // -- sp[(argc + 6) * 4] : first JS argument | 846 // -- sp[(argc + 5) * 4] : first JS argument |
| 845 // -- sp[(argc + 7) * 4] : receiver | 847 // -- sp[(argc + 6) * 4] : receiver |
| 846 // ----------------------------------- | 848 // ----------------------------------- |
| 847 // Save calling context. | |
| 848 __ sw(cp, MemOperand(sp)); | |
| 849 // Get the function and setup the context. | 849 // Get the function and setup the context. |
| 850 Handle<JSFunction> function = optimization.constant_function(); | 850 Handle<JSFunction> function = optimization.constant_function(); |
| 851 __ LoadHeapObject(t1, function); | 851 __ LoadHeapObject(t1, function); |
| 852 __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset)); | 852 __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset)); |
| 853 __ sw(t1, MemOperand(sp, 2 * kPointerSize)); | |
| 854 | 853 |
| 855 // Pass the additional arguments. | 854 // Pass the additional arguments. |
| 856 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 855 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
| 857 Handle<Object> call_data(api_call_info->data(), masm->isolate()); | 856 Handle<Object> call_data(api_call_info->data(), masm->isolate()); |
| 858 if (masm->isolate()->heap()->InNewSpace(*call_data)) { | 857 if (masm->isolate()->heap()->InNewSpace(*call_data)) { |
| 859 __ li(a0, api_call_info); | 858 __ li(a0, api_call_info); |
| 860 __ lw(t2, FieldMemOperand(a0, CallHandlerInfo::kDataOffset)); | 859 __ lw(t2, FieldMemOperand(a0, CallHandlerInfo::kDataOffset)); |
| 861 } else { | 860 } else { |
| 862 __ li(t2, call_data); | 861 __ li(t2, call_data); |
| 863 } | 862 } |
| 864 // Store call data. | 863 |
| 865 __ sw(t2, MemOperand(sp, 3 * kPointerSize)); | |
| 866 // Store isolate. | |
| 867 __ li(t3, Operand(ExternalReference::isolate_address(masm->isolate()))); | 864 __ li(t3, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 868 __ sw(t3, MemOperand(sp, 4 * kPointerSize)); | 865 // Store JS function, call data, isolate ReturnValue default and ReturnValue. |
| 869 // Store ReturnValue default and ReturnValue. | 866 __ sw(t1, MemOperand(sp, 1 * kPointerSize)); |
| 867 __ sw(t2, MemOperand(sp, 2 * kPointerSize)); |
| 868 __ sw(t3, MemOperand(sp, 3 * kPointerSize)); |
| 870 __ LoadRoot(t1, Heap::kUndefinedValueRootIndex); | 869 __ LoadRoot(t1, Heap::kUndefinedValueRootIndex); |
| 870 __ sw(t1, MemOperand(sp, 4 * kPointerSize)); |
| 871 __ sw(t1, MemOperand(sp, 5 * kPointerSize)); | 871 __ sw(t1, MemOperand(sp, 5 * kPointerSize)); |
| 872 __ sw(t1, MemOperand(sp, 6 * kPointerSize)); | |
| 873 | 872 |
| 874 // Prepare arguments. | 873 // Prepare arguments. |
| 875 __ Addu(a2, sp, Operand((kFastApiCallArguments - 1) * kPointerSize)); | 874 __ Addu(a2, sp, Operand(5 * kPointerSize)); |
| 876 | 875 |
| 877 // Allocate the v8::Arguments structure in the arguments' space since | 876 // Allocate the v8::Arguments structure in the arguments' space since |
| 878 // it's not controlled by GC. | 877 // it's not controlled by GC. |
| 879 const int kApiStackSpace = 4; | 878 const int kApiStackSpace = 4; |
| 880 | 879 |
| 881 FrameScope frame_scope(masm, StackFrame::MANUAL); | 880 FrameScope frame_scope(masm, StackFrame::MANUAL); |
| 882 __ EnterExitFrame(false, kApiStackSpace); | 881 __ EnterExitFrame(false, kApiStackSpace); |
| 883 | 882 |
| 884 // a0 = v8::Arguments& | 883 // a0 = v8::Arguments& |
| 885 // Arguments is built at sp + 1 (sp is a reserved spot for ra). | 884 // Arguments is built at sp + 1 (sp is a reserved spot for ra). |
| (...skipping 18 matching lines...) Expand all Loading... |
| 904 ExternalReference(&fun, | 903 ExternalReference(&fun, |
| 905 type, | 904 type, |
| 906 masm->isolate()); | 905 masm->isolate()); |
| 907 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); | 906 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); |
| 908 ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL; | 907 ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL; |
| 909 ApiFunction thunk_fun(thunk_address); | 908 ApiFunction thunk_fun(thunk_address); |
| 910 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, | 909 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, |
| 911 masm->isolate()); | 910 masm->isolate()); |
| 912 | 911 |
| 913 AllowExternalCallThatCantCauseGC scope(masm); | 912 AllowExternalCallThatCantCauseGC scope(masm); |
| 914 MemOperand context_restore_operand( | |
| 915 fp, 2 * kPointerSize); | |
| 916 MemOperand return_value_operand( | |
| 917 fp, (kFastApiCallArguments + 1) * kPointerSize); | |
| 918 __ CallApiFunctionAndReturn(ref, | 913 __ CallApiFunctionAndReturn(ref, |
| 919 function_address, | 914 function_address, |
| 920 thunk_ref, | 915 thunk_ref, |
| 921 a1, | 916 a1, |
| 922 kStackUnwindSpace, | 917 kStackUnwindSpace, |
| 923 return_value_operand, | 918 kFastApiCallArguments + 1); |
| 924 restore_context ? | |
| 925 &context_restore_operand : NULL); | |
| 926 } | 919 } |
| 927 | 920 |
| 928 | 921 |
| 929 // Generate call to api function. | 922 // Generate call to api function. |
| 930 static void GenerateFastApiCall(MacroAssembler* masm, | 923 static void GenerateFastApiCall(MacroAssembler* masm, |
| 931 const CallOptimization& optimization, | 924 const CallOptimization& optimization, |
| 932 Register receiver, | 925 Register receiver, |
| 933 Register scratch, | 926 Register scratch, |
| 934 int argc, | 927 int argc, |
| 935 Register* values) { | 928 Register* values) { |
| 936 ASSERT(optimization.is_simple_api_call()); | 929 ASSERT(optimization.is_simple_api_call()); |
| 937 ASSERT(!receiver.is(scratch)); | 930 ASSERT(!receiver.is(scratch)); |
| 938 | 931 |
| 939 const int stack_space = kFastApiCallArguments + argc + 1; | 932 const int stack_space = kFastApiCallArguments + argc + 1; |
| 940 const int kHolderIndex = kFastApiCallArguments + | |
| 941 FunctionCallbackArguments::kHolderIndex - 1; | |
| 942 // Assign stack space for the call arguments. | 933 // Assign stack space for the call arguments. |
| 943 __ Subu(sp, sp, Operand(stack_space * kPointerSize)); | 934 __ Subu(sp, sp, Operand(stack_space * kPointerSize)); |
| 944 // Write holder to stack frame. | 935 // Write holder to stack frame. |
| 945 __ sw(receiver, MemOperand(sp, kHolderIndex * kPointerSize)); | 936 __ sw(receiver, MemOperand(sp, 0)); |
| 946 // Write receiver to stack frame. | 937 // Write receiver to stack frame. |
| 947 int index = stack_space - 1; | 938 int index = stack_space - 1; |
| 948 __ sw(receiver, MemOperand(sp, index * kPointerSize)); | 939 __ sw(receiver, MemOperand(sp, index * kPointerSize)); |
| 949 // Write the arguments to stack frame. | 940 // Write the arguments to stack frame. |
| 950 for (int i = 0; i < argc; i++) { | 941 for (int i = 0; i < argc; i++) { |
| 951 ASSERT(!receiver.is(values[i])); | 942 ASSERT(!receiver.is(values[i])); |
| 952 ASSERT(!scratch.is(values[i])); | 943 ASSERT(!scratch.is(values[i])); |
| 953 __ sw(receiver, MemOperand(sp, index-- * kPointerSize)); | 944 __ sw(receiver, MemOperand(sp, index-- * kPointerSize)); |
| 954 } | 945 } |
| 955 | 946 |
| 956 GenerateFastApiDirectCall(masm, optimization, argc, true); | 947 GenerateFastApiDirectCall(masm, optimization, argc); |
| 957 } | 948 } |
| 958 | 949 |
| 959 | 950 |
| 960 class CallInterceptorCompiler BASE_EMBEDDED { | 951 class CallInterceptorCompiler BASE_EMBEDDED { |
| 961 public: | 952 public: |
| 962 CallInterceptorCompiler(StubCompiler* stub_compiler, | 953 CallInterceptorCompiler(StubCompiler* stub_compiler, |
| 963 const ParameterCount& arguments, | 954 const ParameterCount& arguments, |
| 964 Register name, | 955 Register name, |
| 965 Code::ExtraICState extra_ic_state) | 956 Code::ExtraICState extra_ic_state) |
| 966 : stub_compiler_(stub_compiler), | 957 : stub_compiler_(stub_compiler), |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 } else { | 1051 } else { |
| 1061 // CheckPrototypes has a side effect of fetching a 'holder' | 1052 // CheckPrototypes has a side effect of fetching a 'holder' |
| 1062 // for API (object which is instanceof for the signature). It's | 1053 // for API (object which is instanceof for the signature). It's |
| 1063 // safe to omit it here, as if present, it should be fetched | 1054 // safe to omit it here, as if present, it should be fetched |
| 1064 // by the previous CheckPrototypes. | 1055 // by the previous CheckPrototypes. |
| 1065 ASSERT(depth2 == kInvalidProtoDepth); | 1056 ASSERT(depth2 == kInvalidProtoDepth); |
| 1066 } | 1057 } |
| 1067 | 1058 |
| 1068 // Invoke function. | 1059 // Invoke function. |
| 1069 if (can_do_fast_api_call) { | 1060 if (can_do_fast_api_call) { |
| 1070 GenerateFastApiDirectCall( | 1061 GenerateFastApiDirectCall(masm, optimization, arguments_.immediate()); |
| 1071 masm, optimization, arguments_.immediate(), false); | |
| 1072 } else { | 1062 } else { |
| 1073 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 1063 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) |
| 1074 ? CALL_AS_FUNCTION | 1064 ? CALL_AS_FUNCTION |
| 1075 : CALL_AS_METHOD; | 1065 : CALL_AS_METHOD; |
| 1076 Handle<JSFunction> function = optimization.constant_function(); | 1066 Handle<JSFunction> function = optimization.constant_function(); |
| 1077 ParameterCount expected(function); | 1067 ParameterCount expected(function); |
| 1078 __ InvokeFunction(function, expected, arguments_, | 1068 __ InvokeFunction(function, expected, arguments_, |
| 1079 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 1069 JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 1080 } | 1070 } |
| 1081 | 1071 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1178 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
| 1189 Register object_reg, | 1179 Register object_reg, |
| 1190 Handle<JSObject> holder, | 1180 Handle<JSObject> holder, |
| 1191 Register holder_reg, | 1181 Register holder_reg, |
| 1192 Register scratch1, | 1182 Register scratch1, |
| 1193 Register scratch2, | 1183 Register scratch2, |
| 1194 Handle<Name> name, | 1184 Handle<Name> name, |
| 1195 int save_at_depth, | 1185 int save_at_depth, |
| 1196 Label* miss, | 1186 Label* miss, |
| 1197 PrototypeCheckType check) { | 1187 PrototypeCheckType check) { |
| 1198 const int kHolderIndex = kFastApiCallArguments + | |
| 1199 FunctionCallbackArguments::kHolderIndex - 1; | |
| 1200 // Make sure that the type feedback oracle harvests the receiver map. | 1188 // Make sure that the type feedback oracle harvests the receiver map. |
| 1201 // TODO(svenpanne) Remove this hack when all ICs are reworked. | 1189 // TODO(svenpanne) Remove this hack when all ICs are reworked. |
| 1202 __ li(scratch1, Operand(Handle<Map>(object->map()))); | 1190 __ li(scratch1, Operand(Handle<Map>(object->map()))); |
| 1203 | 1191 |
| 1204 Handle<JSObject> first = object; | 1192 Handle<JSObject> first = object; |
| 1205 // Make sure there's no overlap between holder and object registers. | 1193 // Make sure there's no overlap between holder and object registers. |
| 1206 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 1194 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
| 1207 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 1195 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
| 1208 && !scratch2.is(scratch1)); | 1196 && !scratch2.is(scratch1)); |
| 1209 | 1197 |
| 1210 // Keep track of the current object in register reg. | 1198 // Keep track of the current object in register reg. |
| 1211 Register reg = object_reg; | 1199 Register reg = object_reg; |
| 1212 int depth = 0; | 1200 int depth = 0; |
| 1213 | 1201 |
| 1214 if (save_at_depth == depth) { | 1202 if (save_at_depth == depth) { |
| 1215 __ sw(reg, MemOperand(sp, kHolderIndex * kPointerSize)); | 1203 __ sw(reg, MemOperand(sp)); |
| 1216 } | 1204 } |
| 1217 | 1205 |
| 1218 // Check the maps in the prototype chain. | 1206 // Check the maps in the prototype chain. |
| 1219 // Traverse the prototype chain from the object and do map checks. | 1207 // Traverse the prototype chain from the object and do map checks. |
| 1220 Handle<JSObject> current = object; | 1208 Handle<JSObject> current = object; |
| 1221 while (!current.is_identical_to(holder)) { | 1209 while (!current.is_identical_to(holder)) { |
| 1222 ++depth; | 1210 ++depth; |
| 1223 | 1211 |
| 1224 // Only global objects and objects that do not require access | 1212 // Only global objects and objects that do not require access |
| 1225 // checks are allowed in stubs. | 1213 // checks are allowed in stubs. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1263 // The prototype is in new space; we cannot store a reference to it | 1251 // The prototype is in new space; we cannot store a reference to it |
| 1264 // in the code. Load it from the map. | 1252 // in the code. Load it from the map. |
| 1265 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); | 1253 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); |
| 1266 } else { | 1254 } else { |
| 1267 // The prototype is in old space; load it directly. | 1255 // The prototype is in old space; load it directly. |
| 1268 __ li(reg, Operand(prototype)); | 1256 __ li(reg, Operand(prototype)); |
| 1269 } | 1257 } |
| 1270 } | 1258 } |
| 1271 | 1259 |
| 1272 if (save_at_depth == depth) { | 1260 if (save_at_depth == depth) { |
| 1273 __ sw(reg, MemOperand(sp, kHolderIndex * kPointerSize)); | 1261 __ sw(reg, MemOperand(sp)); |
| 1274 } | 1262 } |
| 1275 | 1263 |
| 1276 // Go to the next object in the prototype chain. | 1264 // Go to the next object in the prototype chain. |
| 1277 current = prototype; | 1265 current = prototype; |
| 1278 } | 1266 } |
| 1279 | 1267 |
| 1280 // Log the check depth. | 1268 // Log the check depth. |
| 1281 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 1269 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1282 | 1270 |
| 1283 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1271 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 const int kApiStackSpace = 1; | 1451 const int kApiStackSpace = 1; |
| 1464 FrameScope frame_scope(masm(), StackFrame::MANUAL); | 1452 FrameScope frame_scope(masm(), StackFrame::MANUAL); |
| 1465 __ EnterExitFrame(false, kApiStackSpace); | 1453 __ EnterExitFrame(false, kApiStackSpace); |
| 1466 | 1454 |
| 1467 // Create AccessorInfo instance on the stack above the exit frame with | 1455 // Create AccessorInfo instance on the stack above the exit frame with |
| 1468 // scratch2 (internal::Object** args_) as the data. | 1456 // scratch2 (internal::Object** args_) as the data. |
| 1469 __ sw(a2, MemOperand(sp, kPointerSize)); | 1457 __ sw(a2, MemOperand(sp, kPointerSize)); |
| 1470 // (second argument - a1) = AccessorInfo& | 1458 // (second argument - a1) = AccessorInfo& |
| 1471 __ Addu(a1, sp, kPointerSize); | 1459 __ Addu(a1, sp, kPointerSize); |
| 1472 | 1460 |
| 1473 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; | 1461 const int kStackUnwindSpace = kFastApiCallArguments + 1; |
| 1474 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1462 Address getter_address = v8::ToCData<Address>(callback->getter()); |
| 1475 ApiFunction fun(getter_address); | 1463 ApiFunction fun(getter_address); |
| 1476 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; | 1464 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; |
| 1477 ExternalReference ref = ExternalReference(&fun, type, isolate()); | 1465 ExternalReference ref = ExternalReference(&fun, type, isolate()); |
| 1478 | 1466 |
| 1479 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); | 1467 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); |
| 1480 ExternalReference::Type thunk_type = | 1468 ExternalReference::Type thunk_type = |
| 1481 ExternalReference::PROFILING_GETTER_CALL; | 1469 ExternalReference::PROFILING_GETTER_CALL; |
| 1482 ApiFunction thunk_fun(thunk_address); | 1470 ApiFunction thunk_fun(thunk_address); |
| 1483 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, | 1471 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, |
| 1484 isolate()); | 1472 isolate()); |
| 1485 __ CallApiFunctionAndReturn(ref, | 1473 __ CallApiFunctionAndReturn(ref, |
| 1486 getter_address, | 1474 getter_address, |
| 1487 thunk_ref, | 1475 thunk_ref, |
| 1488 a2, | 1476 a2, |
| 1489 kStackUnwindSpace, | 1477 kStackUnwindSpace, |
| 1490 MemOperand(fp, 6 * kPointerSize), | 1478 6); |
| 1491 NULL); | |
| 1492 } | 1479 } |
| 1493 | 1480 |
| 1494 | 1481 |
| 1495 void BaseLoadStubCompiler::GenerateLoadInterceptor( | 1482 void BaseLoadStubCompiler::GenerateLoadInterceptor( |
| 1496 Register holder_reg, | 1483 Register holder_reg, |
| 1497 Handle<JSObject> object, | 1484 Handle<JSObject> object, |
| 1498 Handle<JSObject> interceptor_holder, | 1485 Handle<JSObject> interceptor_holder, |
| 1499 LookupResult* lookup, | 1486 LookupResult* lookup, |
| 1500 Handle<Name> name) { | 1487 Handle<Name> name) { |
| 1501 ASSERT(interceptor_holder->HasNamedInterceptor()); | 1488 ASSERT(interceptor_holder->HasNamedInterceptor()); |
| (...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2564 | 2551 |
| 2565 __ IncrementCounter(counters->call_const(), 1, a0, a3); | 2552 __ IncrementCounter(counters->call_const(), 1, a0, a3); |
| 2566 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); | 2553 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); |
| 2567 | 2554 |
| 2568 ReserveSpaceForFastApiCall(masm(), a0); | 2555 ReserveSpaceForFastApiCall(masm(), a0); |
| 2569 | 2556 |
| 2570 // Check that the maps haven't changed and find a Holder as a side effect. | 2557 // Check that the maps haven't changed and find a Holder as a side effect. |
| 2571 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, name, | 2558 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, name, |
| 2572 depth, &miss); | 2559 depth, &miss); |
| 2573 | 2560 |
| 2574 GenerateFastApiDirectCall(masm(), optimization, argc, false); | 2561 GenerateFastApiDirectCall(masm(), optimization, argc); |
| 2575 | 2562 |
| 2576 __ bind(&miss); | 2563 __ bind(&miss); |
| 2577 FreeSpaceForFastApiCall(masm()); | 2564 FreeSpaceForFastApiCall(masm()); |
| 2578 | 2565 |
| 2579 __ bind(&miss_before_stack_reserved); | 2566 __ bind(&miss_before_stack_reserved); |
| 2580 GenerateMissBranch(); | 2567 GenerateMissBranch(); |
| 2581 | 2568 |
| 2582 // Return the generated code. | 2569 // Return the generated code. |
| 2583 return GetCode(function); | 2570 return GetCode(function); |
| 2584 } | 2571 } |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3207 // ----------------------------------- | 3194 // ----------------------------------- |
| 3208 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); | 3195 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); |
| 3209 } | 3196 } |
| 3210 | 3197 |
| 3211 | 3198 |
| 3212 #undef __ | 3199 #undef __ |
| 3213 | 3200 |
| 3214 } } // namespace v8::internal | 3201 } } // namespace v8::internal |
| 3215 | 3202 |
| 3216 #endif // V8_TARGET_ARCH_MIPS | 3203 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |