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

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

Issue 148333003: crankshaft support for api method calls (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix 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/arm/simulator-arm.cc ('k') | src/hydrogen.h » ('j') | 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 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 const CallOptimization& optimization, 781 const CallOptimization& optimization,
782 int argc, 782 int argc,
783 Register holder_in, 783 Register holder_in,
784 bool restore_context) { 784 bool restore_context) {
785 ASSERT(optimization.is_simple_api_call()); 785 ASSERT(optimization.is_simple_api_call());
786 786
787 // Abi for CallApiFunctionStub. 787 // Abi for CallApiFunctionStub.
788 Register callee = r0; 788 Register callee = r0;
789 Register call_data = r4; 789 Register call_data = r4;
790 Register holder = r2; 790 Register holder = r2;
791 Register api_function_address = r3; 791 Register api_function_address = r1;
792 Register thunk_arg = r1;
793 792
794 // Put holder in place. 793 // Put holder in place.
795 __ Move(holder, holder_in); 794 __ Move(holder, holder_in);
796 795
797 Isolate* isolate = masm->isolate(); 796 Isolate* isolate = masm->isolate();
798 Handle<JSFunction> function = optimization.constant_function(); 797 Handle<JSFunction> function = optimization.constant_function();
799 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 798 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
800 Handle<Object> call_data_obj(api_call_info->data(), isolate); 799 Handle<Object> call_data_obj(api_call_info->data(), isolate);
801 800
802 // Put callee in place. 801 // Put callee in place.
(...skipping 12 matching lines...) Expand all
815 } 814 }
816 815
817 // Put api_function_address in place. 816 // Put api_function_address in place.
818 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 817 Address function_address = v8::ToCData<Address>(api_call_info->callback());
819 ApiFunction fun(function_address); 818 ApiFunction fun(function_address);
820 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 819 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
821 ExternalReference ref = ExternalReference(&fun, 820 ExternalReference ref = ExternalReference(&fun,
822 type, 821 type,
823 masm->isolate()); 822 masm->isolate());
824 __ mov(api_function_address, Operand(ref)); 823 __ mov(api_function_address, Operand(ref));
825 __ mov(thunk_arg, Operand(reinterpret_cast<int32_t>(function_address)));
826 824
827 // Jump to stub. 825 // Jump to stub.
828 CallApiFunctionStub stub(restore_context, call_data_undefined, argc); 826 CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
829 __ TailCallStub(&stub); 827 __ TailCallStub(&stub);
830 } 828 }
831 829
832 830
833 // Generates call to API function.
834 static void GenerateFastApiCall(MacroAssembler* masm,
835 const CallOptimization& optimization,
836 int argc,
837 Handle<Map> map_to_holder,
838 CallOptimization::HolderLookup holder_lookup) {
839 Counters* counters = masm->isolate()->counters();
840 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r1);
841
842 // Move holder to a register
843 Register holder_reg = r2;
844 switch (holder_lookup) {
845 case CallOptimization::kHolderIsReceiver:
846 {
847 ASSERT(map_to_holder.is_null());
848 __ ldr(holder_reg, MemOperand(sp, argc * kPointerSize));
849 }
850 break;
851 case CallOptimization::kHolderIsPrototypeOfMap:
852 {
853 Handle<JSObject> holder(JSObject::cast(map_to_holder->prototype()));
854 if (!masm->isolate()->heap()->InNewSpace(*holder)) {
855 __ Move(holder_reg, holder);
856 } else {
857 __ Move(holder_reg, map_to_holder);
858 __ ldr(holder_reg,
859 FieldMemOperand(holder_reg, Map::kPrototypeOffset));
860 }
861 }
862 break;
863 case CallOptimization::kHolderNotFound:
864 UNREACHABLE();
865 }
866 GenerateFastApiCallBody(masm,
867 optimization,
868 argc,
869 holder_reg,
870 false);
871 }
872
873
874 // Generate call to api function. 831 // Generate call to api function.
875 static void GenerateFastApiCall(MacroAssembler* masm, 832 static void GenerateFastApiCall(MacroAssembler* masm,
876 const CallOptimization& optimization, 833 const CallOptimization& optimization,
877 Register receiver, 834 Register receiver,
878 Register scratch, 835 Register scratch,
879 int argc, 836 int argc,
880 Register* values) { 837 Register* values) {
881 ASSERT(!receiver.is(scratch)); 838 ASSERT(!receiver.is(scratch));
882 __ push(receiver); 839 __ push(receiver);
883 // Write the arguments to stack frame. 840 // Write the arguments to stack frame.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 925
969 // Check that the maps from interceptor's holder to constant function's 926 // Check that the maps from interceptor's holder to constant function's
970 // holder haven't changed and thus we can use cached constant function. 927 // holder haven't changed and thus we can use cached constant function.
971 if (*interceptor_holder != lookup->holder()) { 928 if (*interceptor_holder != lookup->holder()) {
972 stub_compiler_->CheckPrototypes( 929 stub_compiler_->CheckPrototypes(
973 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder, 930 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder,
974 handle(lookup->holder()), scratch1, scratch2, scratch3, 931 handle(lookup->holder()), scratch1, scratch2, scratch3,
975 name, miss_label); 932 name, miss_label);
976 } 933 }
977 934
978 Handle<Map> lookup_map; 935 Handle<JSFunction> function = optimization.constant_function();
979 CallOptimization::HolderLookup holder_lookup = 936 __ Move(r0, receiver);
980 CallOptimization::kHolderNotFound; 937 stub_compiler_->GenerateJumpFunction(object, function);
981 if (optimization.is_simple_api_call() &&
982 !lookup->holder()->IsGlobalObject()) {
983 lookup_map = optimization.LookupHolderOfExpectedType(
984 object, object, interceptor_holder, &holder_lookup);
985 if (holder_lookup == CallOptimization::kHolderNotFound) {
986 lookup_map =
987 optimization.LookupHolderOfExpectedType(
988 object,
989 interceptor_holder,
990 Handle<JSObject>(lookup->holder()),
991 &holder_lookup);
992 }
993 }
994
995 // Invoke function.
996 if (holder_lookup != CallOptimization::kHolderNotFound) {
997 int argc = arguments_.immediate();
998 GenerateFastApiCall(masm,
999 optimization,
1000 argc,
1001 lookup_map,
1002 holder_lookup);
1003 } else {
1004 Handle<JSFunction> function = optimization.constant_function();
1005 __ Move(r0, receiver);
1006 stub_compiler_->GenerateJumpFunction(object, function);
1007 }
1008 938
1009 // Invoke a regular function. 939 // Invoke a regular function.
1010 __ bind(&regular_invoke); 940 __ bind(&regular_invoke);
1011 } 941 }
1012 942
1013 void CompileRegular(MacroAssembler* masm, 943 void CompileRegular(MacroAssembler* masm,
1014 Handle<JSObject> object, 944 Handle<JSObject> object,
1015 Register receiver, 945 Register receiver,
1016 Register scratch1, 946 Register scratch1,
1017 Register scratch2, 947 Register scratch2,
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex); 1247 __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
1318 __ mov(scratch4(), scratch3()); 1248 __ mov(scratch4(), scratch3());
1319 __ Push(scratch3(), scratch4()); 1249 __ Push(scratch3(), scratch4());
1320 __ mov(scratch4(), 1250 __ mov(scratch4(),
1321 Operand(ExternalReference::isolate_address(isolate()))); 1251 Operand(ExternalReference::isolate_address(isolate())));
1322 __ Push(scratch4(), reg); 1252 __ Push(scratch4(), reg);
1323 __ mov(scratch2(), sp); // scratch2 = PropertyAccessorInfo::args_ 1253 __ mov(scratch2(), sp); // scratch2 = PropertyAccessorInfo::args_
1324 __ push(name()); 1254 __ push(name());
1325 1255
1326 // Abi for CallApiGetter 1256 // Abi for CallApiGetter
1327 Register getter_address_reg = r3; 1257 Register getter_address_reg = r2;
1328 Register thunk_last_arg = r2;
1329 1258
1330 Address getter_address = v8::ToCData<Address>(callback->getter()); 1259 Address getter_address = v8::ToCData<Address>(callback->getter());
1331 ApiFunction fun(getter_address); 1260 ApiFunction fun(getter_address);
1332 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 1261 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
1333 ExternalReference ref = ExternalReference(&fun, type, isolate()); 1262 ExternalReference ref = ExternalReference(&fun, type, isolate());
1334 __ mov(getter_address_reg, Operand(ref)); 1263 __ mov(getter_address_reg, Operand(ref));
1335 __ mov(thunk_last_arg, Operand(reinterpret_cast<int32_t>(getter_address)));
1336 1264
1337 CallApiGetterStub stub; 1265 CallApiGetterStub stub;
1338 __ TailCallStub(&stub); 1266 __ TailCallStub(&stub);
1339 } 1267 }
1340 1268
1341 1269
1342 void LoadStubCompiler::GenerateLoadInterceptor( 1270 void LoadStubCompiler::GenerateLoadInterceptor(
1343 Register holder_reg, 1271 Register holder_reg,
1344 Handle<Object> object, 1272 Handle<Object> object,
1345 Handle<JSObject> interceptor_holder, 1273 Handle<JSObject> interceptor_holder,
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 index.translate(holder), Representation::Tagged()); 1421 index.translate(holder), Representation::Tagged());
1494 GenerateJumpFunction(object, r1, &miss); 1422 GenerateJumpFunction(object, r1, &miss);
1495 1423
1496 HandlerFrontendFooter(&miss); 1424 HandlerFrontendFooter(&miss);
1497 1425
1498 // Return the generated code. 1426 // Return the generated code.
1499 return GetCode(Code::FAST, name); 1427 return GetCode(Code::FAST, name);
1500 } 1428 }
1501 1429
1502 1430
1503 Handle<Code> CallStubCompiler::CompileFastApiCall(
1504 const CallOptimization& optimization,
1505 Handle<Object> object,
1506 Handle<JSObject> holder,
1507 Handle<Cell> cell,
1508 Handle<JSFunction> function,
1509 Handle<String> name) {
1510 Counters* counters = isolate()->counters();
1511
1512 ASSERT(optimization.is_simple_api_call());
1513 // Bail out if object is a global object as we don't want to
1514 // repatch it to global receiver.
1515 if (object->IsGlobalObject()) return Handle<Code>::null();
1516 if (!cell.is_null()) return Handle<Code>::null();
1517 if (!object->IsJSObject()) return Handle<Code>::null();
1518 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1519 CallOptimization::HolderLookup holder_lookup =
1520 CallOptimization::kHolderNotFound;
1521 Handle<Map> lookup_map = optimization.LookupHolderOfExpectedType(
1522 receiver, receiver, holder, &holder_lookup);
1523 if (holder_lookup == CallOptimization::kHolderNotFound) {
1524 return Handle<Code>::null();
1525 }
1526
1527 Label miss;
1528 GenerateNameCheck(name, &miss);
1529
1530 // Get the receiver from the stack.
1531 const int argc = arguments().immediate();
1532 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
1533
1534 // Check that the receiver isn't a smi.
1535 __ JumpIfSmi(r1, &miss);
1536
1537 __ IncrementCounter(counters->call_const(), 1, r0, r3);
1538
1539 // Check that the maps haven't changed and find a Holder as a side effect.
1540 CheckPrototypes(
1541 IC::CurrentTypeOf(object, isolate()),
1542 r1, holder, r0, r3, r4, name, &miss);
1543
1544 GenerateFastApiCall(
1545 masm(), optimization, argc, lookup_map, holder_lookup);
1546
1547 HandlerFrontendFooter(&miss);
1548
1549 // Return the generated code.
1550 return GetCode(function);
1551 }
1552
1553
1554 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 1431 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
1555 Label success; 1432 Label success;
1556 // Check that the object is a boolean. 1433 // Check that the object is a boolean.
1557 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 1434 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
1558 __ cmp(object, ip); 1435 __ cmp(object, ip);
1559 __ b(eq, &success); 1436 __ b(eq, &success);
1560 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 1437 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
1561 __ cmp(object, ip); 1438 __ cmp(object, ip);
1562 __ b(ne, miss); 1439 __ b(ne, miss);
1563 __ bind(&success); 1440 __ bind(&success);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1705 return GetCode(Code::FAST, name); 1582 return GetCode(Code::FAST, name);
1706 } 1583 }
1707 1584
1708 1585
1709 Handle<Code> CallStubCompiler::CompileCallGlobal( 1586 Handle<Code> CallStubCompiler::CompileCallGlobal(
1710 Handle<JSObject> object, 1587 Handle<JSObject> object,
1711 Handle<GlobalObject> holder, 1588 Handle<GlobalObject> holder,
1712 Handle<PropertyCell> cell, 1589 Handle<PropertyCell> cell,
1713 Handle<JSFunction> function, 1590 Handle<JSFunction> function,
1714 Handle<Name> name) { 1591 Handle<Name> name) {
1715 if (HasCustomCallGenerator(function)) {
1716 Handle<Code> code = CompileCustomCall(
1717 object, holder, cell, function, Handle<String>::cast(name),
1718 Code::NORMAL);
1719 // A null handle means bail out to the regular compiler code below.
1720 if (!code.is_null()) return code;
1721 }
1722
1723 Label miss; 1592 Label miss;
1724 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1593 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1725 // Potentially loads a closure that matches the shared function info of the 1594 // Potentially loads a closure that matches the shared function info of the
1726 // function, rather than function. 1595 // function, rather than function.
1727 GenerateLoadFunctionFromCell(cell, function, &miss); 1596 GenerateLoadFunctionFromCell(cell, function, &miss);
1728 1597
1729 Counters* counters = isolate()->counters(); 1598 Counters* counters = isolate()->counters();
1730 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); 1599 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4);
1731 GenerateJumpFunction(object, r1, function); 1600 GenerateJumpFunction(object, r1, function);
1732 HandlerFrontendFooter(&miss); 1601 HandlerFrontendFooter(&miss);
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
2100 // ----------------------------------- 1969 // -----------------------------------
2101 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1970 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2102 } 1971 }
2103 1972
2104 1973
2105 #undef __ 1974 #undef __
2106 1975
2107 } } // namespace v8::internal 1976 } } // namespace v8::internal
2108 1977
2109 #endif // V8_TARGET_ARCH_ARM 1978 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/simulator-arm.cc ('k') | src/hydrogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698