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 |