| 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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); | 280 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); |
| 281 } | 281 } |
| 282 | 282 |
| 283 | 283 |
| 284 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( | 284 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( |
| 285 MacroAssembler* masm, | 285 MacroAssembler* masm, |
| 286 int index, | 286 int index, |
| 287 Register prototype, | 287 Register prototype, |
| 288 Label* miss) { | 288 Label* miss) { |
| 289 Isolate* isolate = masm->isolate(); | 289 Isolate* isolate = masm->isolate(); |
| 290 // Check we're still in the same context. | |
| 291 __ lw(prototype, | |
| 292 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | |
| 293 ASSERT(!prototype.is(at)); | |
| 294 __ li(at, isolate->global_object()); | |
| 295 __ Branch(miss, ne, prototype, Operand(at)); | |
| 296 // Get the global function with the given index. | 290 // Get the global function with the given index. |
| 297 Handle<JSFunction> function( | 291 Handle<JSFunction> function( |
| 298 JSFunction::cast(isolate->native_context()->get(index))); | 292 JSFunction::cast(isolate->native_context()->get(index))); |
| 293 |
| 294 // Check we're still in the same context. |
| 295 Register scratch = prototype; |
| 296 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); |
| 297 __ lw(scratch, MemOperand(cp, offset)); |
| 298 __ lw(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); |
| 299 __ lw(scratch, MemOperand(scratch, Context::SlotOffset(index))); |
| 300 __ li(at, function); |
| 301 __ Branch(miss, ne, at, Operand(scratch)); |
| 302 |
| 299 // Load its initial map. The global functions all have initial maps. | 303 // Load its initial map. The global functions all have initial maps. |
| 300 __ li(prototype, Handle<Map>(function->initial_map())); | 304 __ li(prototype, Handle<Map>(function->initial_map())); |
| 301 // Load the prototype from the initial map. | 305 // Load the prototype from the initial map. |
| 302 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); | 306 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); |
| 303 } | 307 } |
| 304 | 308 |
| 305 | 309 |
| 306 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, | 310 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, |
| 307 Register dst, | 311 Register dst, |
| 308 Register src, | 312 Register src, |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 const CallOptimization& optimization, | 773 const CallOptimization& optimization, |
| 770 int argc, | 774 int argc, |
| 771 Register holder_in, | 775 Register holder_in, |
| 772 bool restore_context) { | 776 bool restore_context) { |
| 773 ASSERT(optimization.is_simple_api_call()); | 777 ASSERT(optimization.is_simple_api_call()); |
| 774 | 778 |
| 775 // Abi for CallApiFunctionStub. | 779 // Abi for CallApiFunctionStub. |
| 776 Register callee = a0; | 780 Register callee = a0; |
| 777 Register call_data = t0; | 781 Register call_data = t0; |
| 778 Register holder = a2; | 782 Register holder = a2; |
| 779 Register api_function_address = a3; | 783 Register api_function_address = a1; |
| 780 Register thunk_arg = a1; | |
| 781 | 784 |
| 782 // Put holder in place. | 785 // Put holder in place. |
| 783 __ mov(holder, holder_in); | 786 __ mov(holder, holder_in); |
| 784 | 787 |
| 785 Isolate* isolate = masm->isolate(); | 788 Isolate* isolate = masm->isolate(); |
| 786 Handle<JSFunction> function = optimization.constant_function(); | 789 Handle<JSFunction> function = optimization.constant_function(); |
| 787 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 790 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
| 788 Handle<Object> call_data_obj(api_call_info->data(), isolate); | 791 Handle<Object> call_data_obj(api_call_info->data(), isolate); |
| 789 | 792 |
| 790 // Put callee in place. | 793 // Put callee in place. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 803 } | 806 } |
| 804 // Put api_function_address in place. | 807 // Put api_function_address in place. |
| 805 Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 808 Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
| 806 ApiFunction fun(function_address); | 809 ApiFunction fun(function_address); |
| 807 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; | 810 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; |
| 808 ExternalReference ref = | 811 ExternalReference ref = |
| 809 ExternalReference(&fun, | 812 ExternalReference(&fun, |
| 810 type, | 813 type, |
| 811 masm->isolate()); | 814 masm->isolate()); |
| 812 __ li(api_function_address, Operand(ref)); | 815 __ li(api_function_address, Operand(ref)); |
| 813 __ li(thunk_arg, Operand(reinterpret_cast<int32_t>(function_address))); | |
| 814 | 816 |
| 815 // Jump to stub. | 817 // Jump to stub. |
| 816 CallApiFunctionStub stub(restore_context, call_data_undefined, argc); | 818 CallApiFunctionStub stub(restore_context, call_data_undefined, argc); |
| 817 __ TailCallStub(&stub); | 819 __ TailCallStub(&stub); |
| 818 } | 820 } |
| 819 | 821 |
| 820 | 822 |
| 821 // Generates call to API function. | |
| 822 static void GenerateFastApiCall(MacroAssembler* masm, | |
| 823 const CallOptimization& optimization, | |
| 824 int argc, | |
| 825 Handle<Map> map_to_holder, | |
| 826 CallOptimization::HolderLookup holder_lookup) { | |
| 827 Counters* counters = masm->isolate()->counters(); | |
| 828 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a1); | |
| 829 | |
| 830 // Move holder to a register. | |
| 831 Register holder_reg = a2; | |
| 832 switch (holder_lookup) { | |
| 833 case CallOptimization::kHolderIsReceiver: | |
| 834 { | |
| 835 ASSERT(map_to_holder.is_null()); | |
| 836 __ lw(holder_reg, MemOperand(sp, argc * kPointerSize)); | |
| 837 } | |
| 838 break; | |
| 839 case CallOptimization::kHolderIsPrototypeOfMap: | |
| 840 { | |
| 841 Handle<JSObject> holder(JSObject::cast(map_to_holder->prototype())); | |
| 842 if (!masm->isolate()->heap()->InNewSpace(*holder)) { | |
| 843 __ li(holder_reg, holder); | |
| 844 } else { | |
| 845 __ li(holder_reg, map_to_holder); | |
| 846 __ lw(holder_reg, | |
| 847 FieldMemOperand(holder_reg, Map::kPrototypeOffset)); | |
| 848 } | |
| 849 } | |
| 850 break; | |
| 851 case CallOptimization::kHolderNotFound: | |
| 852 UNREACHABLE(); | |
| 853 } | |
| 854 GenerateFastApiCallBody(masm, | |
| 855 optimization, | |
| 856 argc, | |
| 857 holder_reg, | |
| 858 false); | |
| 859 } | |
| 860 | |
| 861 | |
| 862 // Generate call to api function. | 823 // Generate call to api function. |
| 863 static void GenerateFastApiCall(MacroAssembler* masm, | 824 static void GenerateFastApiCall(MacroAssembler* masm, |
| 864 const CallOptimization& optimization, | 825 const CallOptimization& optimization, |
| 865 Register receiver, | 826 Register receiver, |
| 866 Register scratch, | 827 Register scratch, |
| 867 int argc, | 828 int argc, |
| 868 Register* values) { | 829 Register* values) { |
| 869 ASSERT(!receiver.is(scratch)); | 830 ASSERT(!receiver.is(scratch)); |
| 870 __ push(receiver); | 831 __ push(receiver); |
| 871 // Write the arguments to stack frame. | 832 // Write the arguments to stack frame. |
| 872 for (int i = 0; i < argc; i++) { | 833 for (int i = 0; i < argc; i++) { |
| 873 Register arg = values[argc-1-i]; | 834 Register arg = values[argc-1-i]; |
| 874 ASSERT(!receiver.is(arg)); | 835 ASSERT(!receiver.is(arg)); |
| 875 ASSERT(!scratch.is(arg)); | 836 ASSERT(!scratch.is(arg)); |
| 876 __ push(arg); | 837 __ push(arg); |
| 877 } | 838 } |
| 878 | 839 |
| 879 // Stack now matches JSFunction abi. | 840 // Stack now matches JSFunction abi. |
| 880 GenerateFastApiCallBody(masm, | 841 GenerateFastApiCallBody(masm, |
| 881 optimization, | 842 optimization, |
| 882 argc, | 843 argc, |
| 883 receiver, | 844 receiver, |
| 884 true); | 845 true); |
| 885 } | 846 } |
| 886 | 847 |
| 887 | 848 |
| 888 class CallInterceptorCompiler BASE_EMBEDDED { | 849 class CallInterceptorCompiler BASE_EMBEDDED { |
| 889 public: | 850 public: |
| 890 CallInterceptorCompiler(CallStubCompiler* stub_compiler, | 851 CallInterceptorCompiler(CallStubCompiler* stub_compiler, |
| 891 const ParameterCount& arguments, | |
| 892 Register name) | 852 Register name) |
| 893 : stub_compiler_(stub_compiler), | 853 : stub_compiler_(stub_compiler), |
| 894 arguments_(arguments), | |
| 895 name_(name) {} | 854 name_(name) {} |
| 896 | 855 |
| 897 void Compile(MacroAssembler* masm, | 856 void Compile(MacroAssembler* masm, |
| 898 Handle<JSObject> object, | 857 Handle<JSObject> object, |
| 899 Handle<JSObject> holder, | 858 Handle<JSObject> holder, |
| 900 Handle<Name> name, | 859 Handle<Name> name, |
| 901 LookupResult* lookup, | 860 LookupResult* lookup, |
| 902 Register receiver, | 861 Register receiver, |
| 903 Register scratch1, | 862 Register scratch1, |
| 904 Register scratch2, | 863 Register scratch2, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 | 916 |
| 958 // Check that the maps from interceptor's holder to constant function's | 917 // Check that the maps from interceptor's holder to constant function's |
| 959 // holder haven't changed and thus we can use cached constant function. | 918 // holder haven't changed and thus we can use cached constant function. |
| 960 if (*interceptor_holder != lookup->holder()) { | 919 if (*interceptor_holder != lookup->holder()) { |
| 961 stub_compiler_->CheckPrototypes( | 920 stub_compiler_->CheckPrototypes( |
| 962 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder, | 921 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder, |
| 963 handle(lookup->holder()), scratch1, scratch2, scratch3, | 922 handle(lookup->holder()), scratch1, scratch2, scratch3, |
| 964 name, miss_label); | 923 name, miss_label); |
| 965 } | 924 } |
| 966 | 925 |
| 967 Handle<Map> lookup_map; | 926 Handle<JSFunction> function = optimization.constant_function(); |
| 968 CallOptimization::HolderLookup holder_lookup = | 927 __ Move(a0, receiver); |
| 969 CallOptimization::kHolderNotFound; | 928 stub_compiler_->GenerateJumpFunction(object, function); |
| 970 if (optimization.is_simple_api_call() && | |
| 971 !lookup->holder()->IsGlobalObject()) { | |
| 972 lookup_map = optimization.LookupHolderOfExpectedType( | |
| 973 object, object, interceptor_holder, &holder_lookup); | |
| 974 if (holder_lookup == CallOptimization::kHolderNotFound) { | |
| 975 lookup_map = | |
| 976 optimization.LookupHolderOfExpectedType( | |
| 977 object, | |
| 978 interceptor_holder, | |
| 979 Handle<JSObject>(lookup->holder()), | |
| 980 &holder_lookup); | |
| 981 } | |
| 982 } | |
| 983 | |
| 984 // Invoke function. | |
| 985 if (holder_lookup != CallOptimization::kHolderNotFound) { | |
| 986 int argc = arguments_.immediate(); | |
| 987 GenerateFastApiCall(masm, | |
| 988 optimization, | |
| 989 argc, | |
| 990 lookup_map, | |
| 991 holder_lookup); | |
| 992 } else { | |
| 993 Handle<JSFunction> function = optimization.constant_function(); | |
| 994 __ Move(a0, receiver); | |
| 995 stub_compiler_->GenerateJumpFunction(object, function); | |
| 996 } | |
| 997 | 929 |
| 998 // Invoke a regular function. | 930 // Invoke a regular function. |
| 999 __ bind(®ular_invoke); | 931 __ bind(®ular_invoke); |
| 1000 } | 932 } |
| 1001 | 933 |
| 1002 void CompileRegular(MacroAssembler* masm, | 934 void CompileRegular(MacroAssembler* masm, |
| 1003 Handle<JSObject> object, | 935 Handle<JSObject> object, |
| 1004 Register receiver, | 936 Register receiver, |
| 1005 Register scratch1, | 937 Register scratch1, |
| 1006 Register scratch2, | 938 Register scratch2, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 __ pop(name_); | 975 __ pop(name_); |
| 1044 __ pop(holder); | 976 __ pop(holder); |
| 1045 __ pop(receiver); | 977 __ pop(receiver); |
| 1046 } | 978 } |
| 1047 // If interceptor returns no-result sentinel, call the constant function. | 979 // If interceptor returns no-result sentinel, call the constant function. |
| 1048 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); | 980 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); |
| 1049 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); | 981 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); |
| 1050 } | 982 } |
| 1051 | 983 |
| 1052 CallStubCompiler* stub_compiler_; | 984 CallStubCompiler* stub_compiler_; |
| 1053 const ParameterCount& arguments_; | |
| 1054 Register name_; | 985 Register name_; |
| 1055 }; | 986 }; |
| 1056 | 987 |
| 1057 | 988 |
| 1058 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 989 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { |
| 1059 __ Jump(code, RelocInfo::CODE_TARGET); | 990 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1060 } | 991 } |
| 1061 | 992 |
| 1062 | 993 |
| 1063 #undef __ | 994 #undef __ |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 __ sw(scratch3(), MemOperand(sp, 4 * kPointerSize)); | 1237 __ sw(scratch3(), MemOperand(sp, 4 * kPointerSize)); |
| 1307 __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize)); | 1238 __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize)); |
| 1308 __ li(scratch4(), | 1239 __ li(scratch4(), |
| 1309 Operand(ExternalReference::isolate_address(isolate()))); | 1240 Operand(ExternalReference::isolate_address(isolate()))); |
| 1310 __ sw(scratch4(), MemOperand(sp, 2 * kPointerSize)); | 1241 __ sw(scratch4(), MemOperand(sp, 2 * kPointerSize)); |
| 1311 __ sw(reg, MemOperand(sp, 1 * kPointerSize)); | 1242 __ sw(reg, MemOperand(sp, 1 * kPointerSize)); |
| 1312 __ sw(name(), MemOperand(sp, 0 * kPointerSize)); | 1243 __ sw(name(), MemOperand(sp, 0 * kPointerSize)); |
| 1313 __ Addu(scratch2(), sp, 1 * kPointerSize); | 1244 __ Addu(scratch2(), sp, 1 * kPointerSize); |
| 1314 | 1245 |
| 1315 __ mov(a2, scratch2()); // Saved in case scratch2 == a1. | 1246 __ mov(a2, scratch2()); // Saved in case scratch2 == a1. |
| 1316 __ mov(a0, sp); // (first argument - a0) = Handle<Name> | 1247 // Abi for CallApiGetter. |
| 1248 Register getter_address_reg = a2; |
| 1317 | 1249 |
| 1318 const int kApiStackSpace = 1; | |
| 1319 FrameScope frame_scope(masm(), StackFrame::MANUAL); | |
| 1320 __ EnterExitFrame(false, kApiStackSpace); | |
| 1321 | |
| 1322 // Create PropertyAccessorInfo instance on the stack above the exit frame with | |
| 1323 // scratch2 (internal::Object** args_) as the data. | |
| 1324 __ sw(a2, MemOperand(sp, kPointerSize)); | |
| 1325 // (second argument - a1) = AccessorInfo& | |
| 1326 __ Addu(a1, sp, kPointerSize); | |
| 1327 | |
| 1328 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; | |
| 1329 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1250 Address getter_address = v8::ToCData<Address>(callback->getter()); |
| 1330 ApiFunction fun(getter_address); | 1251 ApiFunction fun(getter_address); |
| 1331 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; | 1252 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; |
| 1332 ExternalReference ref = ExternalReference(&fun, type, isolate()); | 1253 ExternalReference ref = ExternalReference(&fun, type, isolate()); |
| 1333 Register getter_address_reg = a3; | |
| 1334 Register thunk_last_arg = a2; | |
| 1335 __ li(getter_address_reg, Operand(ref)); | 1254 __ li(getter_address_reg, Operand(ref)); |
| 1336 __ li(thunk_last_arg, Operand(reinterpret_cast<int32_t>(getter_address))); | |
| 1337 | 1255 |
| 1338 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); | 1256 CallApiGetterStub stub; |
| 1339 ExternalReference::Type thunk_type = | 1257 __ TailCallStub(&stub); |
| 1340 ExternalReference::PROFILING_GETTER_CALL; | |
| 1341 ApiFunction thunk_fun(thunk_address); | |
| 1342 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, | |
| 1343 isolate()); | |
| 1344 __ CallApiFunctionAndReturn(getter_address_reg, | |
| 1345 thunk_ref, | |
| 1346 thunk_last_arg, | |
| 1347 kStackUnwindSpace, | |
| 1348 MemOperand(fp, 6 * kPointerSize), | |
| 1349 NULL); | |
| 1350 } | 1258 } |
| 1351 | 1259 |
| 1352 | 1260 |
| 1353 void LoadStubCompiler::GenerateLoadInterceptor( | 1261 void LoadStubCompiler::GenerateLoadInterceptor( |
| 1354 Register holder_reg, | 1262 Register holder_reg, |
| 1355 Handle<Object> object, | 1263 Handle<Object> object, |
| 1356 Handle<JSObject> interceptor_holder, | 1264 Handle<JSObject> interceptor_holder, |
| 1357 LookupResult* lookup, | 1265 LookupResult* lookup, |
| 1358 Handle<Name> name) { | 1266 Handle<Name> name) { |
| 1359 ASSERT(interceptor_holder->HasNamedInterceptor()); | 1267 ASSERT(interceptor_holder->HasNamedInterceptor()); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1499 index.translate(holder), Representation::Tagged()); | 1407 index.translate(holder), Representation::Tagged()); |
| 1500 GenerateJumpFunction(object, a1, &miss); | 1408 GenerateJumpFunction(object, a1, &miss); |
| 1501 | 1409 |
| 1502 HandlerFrontendFooter(&miss); | 1410 HandlerFrontendFooter(&miss); |
| 1503 | 1411 |
| 1504 // Return the generated code. | 1412 // Return the generated code. |
| 1505 return GetCode(Code::FAST, name); | 1413 return GetCode(Code::FAST, name); |
| 1506 } | 1414 } |
| 1507 | 1415 |
| 1508 | 1416 |
| 1509 Handle<Code> CallStubCompiler::CompileFastApiCall( | |
| 1510 const CallOptimization& optimization, | |
| 1511 Handle<Object> object, | |
| 1512 Handle<JSObject> holder, | |
| 1513 Handle<Cell> cell, | |
| 1514 Handle<JSFunction> function, | |
| 1515 Handle<String> name) { | |
| 1516 | |
| 1517 Counters* counters = isolate()->counters(); | |
| 1518 | |
| 1519 ASSERT(optimization.is_simple_api_call()); | |
| 1520 // Bail out if object is a global object as we don't want to | |
| 1521 // repatch it to global receiver. | |
| 1522 if (object->IsGlobalObject()) return Handle<Code>::null(); | |
| 1523 if (!cell.is_null()) return Handle<Code>::null(); | |
| 1524 if (!object->IsJSObject()) return Handle<Code>::null(); | |
| 1525 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | |
| 1526 CallOptimization::HolderLookup holder_lookup = | |
| 1527 CallOptimization::kHolderNotFound; | |
| 1528 Handle<Map> lookup_map = optimization.LookupHolderOfExpectedType( | |
| 1529 receiver, receiver, holder, &holder_lookup); | |
| 1530 if (holder_lookup == CallOptimization::kHolderNotFound) { | |
| 1531 return Handle<Code>::null(); | |
| 1532 } | |
| 1533 | |
| 1534 Label miss; | |
| 1535 GenerateNameCheck(name, &miss); | |
| 1536 | |
| 1537 // Get the receiver from the stack. | |
| 1538 const int argc = arguments().immediate(); | |
| 1539 __ lw(a1, MemOperand(sp, argc * kPointerSize)); | |
| 1540 | |
| 1541 // Check that the receiver isn't a smi. | |
| 1542 __ JumpIfSmi(a1, &miss); | |
| 1543 | |
| 1544 __ IncrementCounter(counters->call_const(), 1, a0, a3); | |
| 1545 | |
| 1546 // Check that the maps haven't changed and find a Holder as a side effect. | |
| 1547 CheckPrototypes( | |
| 1548 IC::CurrentTypeOf(object, isolate()), | |
| 1549 a1, holder, a0, a3, t0, name, &miss); | |
| 1550 | |
| 1551 GenerateFastApiCall( | |
| 1552 masm(), optimization, argc, lookup_map, holder_lookup); | |
| 1553 | |
| 1554 HandlerFrontendFooter(&miss); | |
| 1555 | |
| 1556 // Return the generated code. | |
| 1557 return GetCode(function); | |
| 1558 } | |
| 1559 | |
| 1560 | |
| 1561 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { | 1417 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { |
| 1562 Label success; | 1418 Label success; |
| 1563 // Check that the object is a boolean. | 1419 // Check that the object is a boolean. |
| 1564 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 1420 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
| 1565 __ Branch(&success, eq, object, Operand(at)); | 1421 __ Branch(&success, eq, object, Operand(at)); |
| 1566 __ LoadRoot(at, Heap::kFalseValueRootIndex); | 1422 __ LoadRoot(at, Heap::kFalseValueRootIndex); |
| 1567 __ Branch(miss, ne, object, Operand(at)); | 1423 __ Branch(miss, ne, object, Operand(at)); |
| 1568 __ bind(&success); | 1424 __ bind(&success); |
| 1569 } | 1425 } |
| 1570 | 1426 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1687 GenerateNameCheck(name, &miss); | 1543 GenerateNameCheck(name, &miss); |
| 1688 | 1544 |
| 1689 // Get the number of arguments. | 1545 // Get the number of arguments. |
| 1690 const int argc = arguments().immediate(); | 1546 const int argc = arguments().immediate(); |
| 1691 LookupResult lookup(isolate()); | 1547 LookupResult lookup(isolate()); |
| 1692 LookupPostInterceptor(holder, name, &lookup); | 1548 LookupPostInterceptor(holder, name, &lookup); |
| 1693 | 1549 |
| 1694 // Get the receiver from the stack. | 1550 // Get the receiver from the stack. |
| 1695 __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 1551 __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
| 1696 | 1552 |
| 1697 CallInterceptorCompiler compiler(this, arguments(), a2); | 1553 CallInterceptorCompiler compiler(this, a2); |
| 1698 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0, | 1554 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0, |
| 1699 &miss); | 1555 &miss); |
| 1700 | 1556 |
| 1701 // Move returned value, the function to call, to a1. | 1557 // Move returned value, the function to call, to a1. |
| 1702 __ mov(a1, v0); | 1558 __ mov(a1, v0); |
| 1703 // Restore receiver. | 1559 // Restore receiver. |
| 1704 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 1560 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
| 1705 | 1561 |
| 1706 GenerateJumpFunction(object, a1, &miss); | 1562 GenerateJumpFunction(object, a1, &miss); |
| 1707 | 1563 |
| 1708 HandlerFrontendFooter(&miss); | 1564 HandlerFrontendFooter(&miss); |
| 1709 | 1565 |
| 1710 // Return the generated code. | 1566 // Return the generated code. |
| 1711 return GetCode(Code::FAST, name); | 1567 return GetCode(Code::FAST, name); |
| 1712 } | 1568 } |
| 1713 | 1569 |
| 1714 | 1570 |
| 1715 Handle<Code> CallStubCompiler::CompileCallGlobal( | 1571 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 1716 Handle<JSObject> object, | 1572 Handle<JSObject> object, |
| 1717 Handle<GlobalObject> holder, | 1573 Handle<GlobalObject> holder, |
| 1718 Handle<PropertyCell> cell, | 1574 Handle<PropertyCell> cell, |
| 1719 Handle<JSFunction> function, | 1575 Handle<JSFunction> function, |
| 1720 Handle<Name> name) { | 1576 Handle<Name> name) { |
| 1721 if (HasCustomCallGenerator(function)) { | |
| 1722 Handle<Code> code = CompileCustomCall( | |
| 1723 object, holder, cell, function, Handle<String>::cast(name), | |
| 1724 Code::NORMAL); | |
| 1725 // A null handle means bail out to the regular compiler code below. | |
| 1726 if (!code.is_null()) return code; | |
| 1727 } | |
| 1728 | |
| 1729 Label miss; | 1577 Label miss; |
| 1730 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | 1578 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 1731 // Potentially loads a closure that matches the shared function info of the | 1579 // Potentially loads a closure that matches the shared function info of the |
| 1732 // function, rather than function. | 1580 // function, rather than function. |
| 1733 GenerateLoadFunctionFromCell(cell, function, &miss); | 1581 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1734 Counters* counters = isolate()->counters(); | 1582 Counters* counters = isolate()->counters(); |
| 1735 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); | 1583 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); |
| 1736 GenerateJumpFunction(object, a1, function); | 1584 GenerateJumpFunction(object, a1, function); |
| 1737 HandlerFrontendFooter(&miss); | 1585 HandlerFrontendFooter(&miss); |
| 1738 | 1586 |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2104 // ----------------------------------- | 1952 // ----------------------------------- |
| 2105 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 1953 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
| 2106 } | 1954 } |
| 2107 | 1955 |
| 2108 | 1956 |
| 2109 #undef __ | 1957 #undef __ |
| 2110 | 1958 |
| 2111 } } // namespace v8::internal | 1959 } } // namespace v8::internal |
| 2112 | 1960 |
| 2113 #endif // V8_TARGET_ARCH_MIPS | 1961 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |