Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: src/mips/stub-cache-mips.cc

Issue 150913002: MIPS: crankshaft support for api method calls (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mips/simulator-mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 const CallOptimization& optimization, 769 const CallOptimization& optimization,
770 int argc, 770 int argc,
771 Register holder_in, 771 Register holder_in,
772 bool restore_context) { 772 bool restore_context) {
773 ASSERT(optimization.is_simple_api_call()); 773 ASSERT(optimization.is_simple_api_call());
774 774
775 // Abi for CallApiFunctionStub. 775 // Abi for CallApiFunctionStub.
776 Register callee = a0; 776 Register callee = a0;
777 Register call_data = t0; 777 Register call_data = t0;
778 Register holder = a2; 778 Register holder = a2;
779 Register api_function_address = a3; 779 Register api_function_address = a1;
780 Register thunk_arg = a1;
781 780
782 // Put holder in place. 781 // Put holder in place.
783 __ mov(holder, holder_in); 782 __ mov(holder, holder_in);
784 783
785 Isolate* isolate = masm->isolate(); 784 Isolate* isolate = masm->isolate();
786 Handle<JSFunction> function = optimization.constant_function(); 785 Handle<JSFunction> function = optimization.constant_function();
787 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 786 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
788 Handle<Object> call_data_obj(api_call_info->data(), isolate); 787 Handle<Object> call_data_obj(api_call_info->data(), isolate);
789 788
790 // Put callee in place. 789 // Put callee in place.
(...skipping 12 matching lines...) Expand all
803 } 802 }
804 // Put api_function_address in place. 803 // Put api_function_address in place.
805 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 804 Address function_address = v8::ToCData<Address>(api_call_info->callback());
806 ApiFunction fun(function_address); 805 ApiFunction fun(function_address);
807 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 806 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
808 ExternalReference ref = 807 ExternalReference ref =
809 ExternalReference(&fun, 808 ExternalReference(&fun,
810 type, 809 type,
811 masm->isolate()); 810 masm->isolate());
812 __ li(api_function_address, Operand(ref)); 811 __ li(api_function_address, Operand(ref));
813 __ li(thunk_arg, Operand(reinterpret_cast<int32_t>(function_address)));
814 812
815 // Jump to stub. 813 // Jump to stub.
816 CallApiFunctionStub stub(restore_context, call_data_undefined, argc); 814 CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
817 __ TailCallStub(&stub); 815 __ TailCallStub(&stub);
818 } 816 }
819 817
820 818
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. 819 // Generate call to api function.
863 static void GenerateFastApiCall(MacroAssembler* masm, 820 static void GenerateFastApiCall(MacroAssembler* masm,
864 const CallOptimization& optimization, 821 const CallOptimization& optimization,
865 Register receiver, 822 Register receiver,
866 Register scratch, 823 Register scratch,
867 int argc, 824 int argc,
868 Register* values) { 825 Register* values) {
869 ASSERT(!receiver.is(scratch)); 826 ASSERT(!receiver.is(scratch));
870 __ push(receiver); 827 __ push(receiver);
871 // Write the arguments to stack frame. 828 // Write the arguments to stack frame.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 914
958 // Check that the maps from interceptor's holder to constant function's 915 // 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. 916 // holder haven't changed and thus we can use cached constant function.
960 if (*interceptor_holder != lookup->holder()) { 917 if (*interceptor_holder != lookup->holder()) {
961 stub_compiler_->CheckPrototypes( 918 stub_compiler_->CheckPrototypes(
962 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder, 919 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder,
963 handle(lookup->holder()), scratch1, scratch2, scratch3, 920 handle(lookup->holder()), scratch1, scratch2, scratch3,
964 name, miss_label); 921 name, miss_label);
965 } 922 }
966 923
967 Handle<Map> lookup_map; 924 Handle<JSFunction> function = optimization.constant_function();
968 CallOptimization::HolderLookup holder_lookup = 925 __ Move(a0, receiver);
969 CallOptimization::kHolderNotFound; 926 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 927
998 // Invoke a regular function. 928 // Invoke a regular function.
999 __ bind(&regular_invoke); 929 __ bind(&regular_invoke);
1000 } 930 }
1001 931
1002 void CompileRegular(MacroAssembler* masm, 932 void CompileRegular(MacroAssembler* masm,
1003 Handle<JSObject> object, 933 Handle<JSObject> object,
1004 Register receiver, 934 Register receiver,
1005 Register scratch1, 935 Register scratch1,
1006 Register scratch2, 936 Register scratch2,
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize)); 1237 __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize));
1308 __ li(scratch4(), 1238 __ li(scratch4(),
1309 Operand(ExternalReference::isolate_address(isolate()))); 1239 Operand(ExternalReference::isolate_address(isolate())));
1310 __ sw(scratch4(), MemOperand(sp, 2 * kPointerSize)); 1240 __ sw(scratch4(), MemOperand(sp, 2 * kPointerSize));
1311 __ sw(reg, MemOperand(sp, 1 * kPointerSize)); 1241 __ sw(reg, MemOperand(sp, 1 * kPointerSize));
1312 __ sw(name(), MemOperand(sp, 0 * kPointerSize)); 1242 __ sw(name(), MemOperand(sp, 0 * kPointerSize));
1313 __ Addu(scratch2(), sp, 1 * kPointerSize); 1243 __ Addu(scratch2(), sp, 1 * kPointerSize);
1314 1244
1315 __ mov(a2, scratch2()); // Saved in case scratch2 == a1. 1245 __ mov(a2, scratch2()); // Saved in case scratch2 == a1.
1316 // Abi for CallApiGetter. 1246 // Abi for CallApiGetter.
1317 Register getter_address_reg = a3; 1247 Register getter_address_reg = a2;
1318 Register thunk_last_arg = a2;
1319 1248
1320 Address getter_address = v8::ToCData<Address>(callback->getter()); 1249 Address getter_address = v8::ToCData<Address>(callback->getter());
1321 ApiFunction fun(getter_address); 1250 ApiFunction fun(getter_address);
1322 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 1251 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
1323 ExternalReference ref = ExternalReference(&fun, type, isolate()); 1252 ExternalReference ref = ExternalReference(&fun, type, isolate());
1324 __ li(getter_address_reg, Operand(ref)); 1253 __ li(getter_address_reg, Operand(ref));
1325 __ li(thunk_last_arg, Operand(reinterpret_cast<int32_t>(getter_address)));
1326 1254
1327 CallApiGetterStub stub; 1255 CallApiGetterStub stub;
1328 __ TailCallStub(&stub); 1256 __ TailCallStub(&stub);
1329 } 1257 }
1330 1258
1331 1259
1332 void LoadStubCompiler::GenerateLoadInterceptor( 1260 void LoadStubCompiler::GenerateLoadInterceptor(
1333 Register holder_reg, 1261 Register holder_reg,
1334 Handle<Object> object, 1262 Handle<Object> object,
1335 Handle<JSObject> interceptor_holder, 1263 Handle<JSObject> interceptor_holder,
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 index.translate(holder), Representation::Tagged()); 1406 index.translate(holder), Representation::Tagged());
1479 GenerateJumpFunction(object, a1, &miss); 1407 GenerateJumpFunction(object, a1, &miss);
1480 1408
1481 HandlerFrontendFooter(&miss); 1409 HandlerFrontendFooter(&miss);
1482 1410
1483 // Return the generated code. 1411 // Return the generated code.
1484 return GetCode(Code::FAST, name); 1412 return GetCode(Code::FAST, name);
1485 } 1413 }
1486 1414
1487 1415
1488 Handle<Code> CallStubCompiler::CompileFastApiCall(
1489 const CallOptimization& optimization,
1490 Handle<Object> object,
1491 Handle<JSObject> holder,
1492 Handle<Cell> cell,
1493 Handle<JSFunction> function,
1494 Handle<String> name) {
1495
1496 Counters* counters = isolate()->counters();
1497
1498 ASSERT(optimization.is_simple_api_call());
1499 // Bail out if object is a global object as we don't want to
1500 // repatch it to global receiver.
1501 if (object->IsGlobalObject()) return Handle<Code>::null();
1502 if (!cell.is_null()) return Handle<Code>::null();
1503 if (!object->IsJSObject()) return Handle<Code>::null();
1504 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1505 CallOptimization::HolderLookup holder_lookup =
1506 CallOptimization::kHolderNotFound;
1507 Handle<Map> lookup_map = optimization.LookupHolderOfExpectedType(
1508 receiver, receiver, holder, &holder_lookup);
1509 if (holder_lookup == CallOptimization::kHolderNotFound) {
1510 return Handle<Code>::null();
1511 }
1512
1513 Label miss;
1514 GenerateNameCheck(name, &miss);
1515
1516 // Get the receiver from the stack.
1517 const int argc = arguments().immediate();
1518 __ lw(a1, MemOperand(sp, argc * kPointerSize));
1519
1520 // Check that the receiver isn't a smi.
1521 __ JumpIfSmi(a1, &miss);
1522
1523 __ IncrementCounter(counters->call_const(), 1, a0, a3);
1524
1525 // Check that the maps haven't changed and find a Holder as a side effect.
1526 CheckPrototypes(
1527 IC::CurrentTypeOf(object, isolate()),
1528 a1, holder, a0, a3, t0, name, &miss);
1529
1530 GenerateFastApiCall(
1531 masm(), optimization, argc, lookup_map, holder_lookup);
1532
1533 HandlerFrontendFooter(&miss);
1534
1535 // Return the generated code.
1536 return GetCode(function);
1537 }
1538
1539
1540 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 1416 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
1541 Label success; 1417 Label success;
1542 // Check that the object is a boolean. 1418 // Check that the object is a boolean.
1543 __ LoadRoot(at, Heap::kTrueValueRootIndex); 1419 __ LoadRoot(at, Heap::kTrueValueRootIndex);
1544 __ Branch(&success, eq, object, Operand(at)); 1420 __ Branch(&success, eq, object, Operand(at));
1545 __ LoadRoot(at, Heap::kFalseValueRootIndex); 1421 __ LoadRoot(at, Heap::kFalseValueRootIndex);
1546 __ Branch(miss, ne, object, Operand(at)); 1422 __ Branch(miss, ne, object, Operand(at));
1547 __ bind(&success); 1423 __ bind(&success);
1548 } 1424 }
1549 1425
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 return GetCode(Code::FAST, name); 1566 return GetCode(Code::FAST, name);
1691 } 1567 }
1692 1568
1693 1569
1694 Handle<Code> CallStubCompiler::CompileCallGlobal( 1570 Handle<Code> CallStubCompiler::CompileCallGlobal(
1695 Handle<JSObject> object, 1571 Handle<JSObject> object,
1696 Handle<GlobalObject> holder, 1572 Handle<GlobalObject> holder,
1697 Handle<PropertyCell> cell, 1573 Handle<PropertyCell> cell,
1698 Handle<JSFunction> function, 1574 Handle<JSFunction> function,
1699 Handle<Name> name) { 1575 Handle<Name> name) {
1700 if (HasCustomCallGenerator(function)) {
1701 Handle<Code> code = CompileCustomCall(
1702 object, holder, cell, function, Handle<String>::cast(name),
1703 Code::NORMAL);
1704 // A null handle means bail out to the regular compiler code below.
1705 if (!code.is_null()) return code;
1706 }
1707
1708 Label miss; 1576 Label miss;
1709 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1577 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1710 // Potentially loads a closure that matches the shared function info of the 1578 // Potentially loads a closure that matches the shared function info of the
1711 // function, rather than function. 1579 // function, rather than function.
1712 GenerateLoadFunctionFromCell(cell, function, &miss); 1580 GenerateLoadFunctionFromCell(cell, function, &miss);
1713 Counters* counters = isolate()->counters(); 1581 Counters* counters = isolate()->counters();
1714 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); 1582 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0);
1715 GenerateJumpFunction(object, a1, function); 1583 GenerateJumpFunction(object, a1, function);
1716 HandlerFrontendFooter(&miss); 1584 HandlerFrontendFooter(&miss);
1717 1585
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
2083 // ----------------------------------- 1951 // -----------------------------------
2084 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1952 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2085 } 1953 }
2086 1954
2087 1955
2088 #undef __ 1956 #undef __
2089 1957
2090 } } // namespace v8::internal 1958 } } // namespace v8::internal
2091 1959
2092 #endif // V8_TARGET_ARCH_MIPS 1960 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/simulator-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698