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

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

Issue 149403003: A64: Synchronize with r19234. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
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/macro-assembler-mips.cc ('k') | src/objects.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 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 Register name, 762 Register name,
763 Handle<JSObject> holder_obj, 763 Handle<JSObject> holder_obj,
764 IC::UtilityId id) { 764 IC::UtilityId id) {
765 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 765 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
766 __ CallExternalReference( 766 __ CallExternalReference(
767 ExternalReference(IC_Utility(id), masm->isolate()), 767 ExternalReference(IC_Utility(id), masm->isolate()),
768 StubCache::kInterceptorArgsLength); 768 StubCache::kInterceptorArgsLength);
769 } 769 }
770 770
771 771
772 static void GenerateFastApiCallBody(MacroAssembler* masm, 772 // Generate call to api function.
773 const CallOptimization& optimization, 773 static void GenerateFastApiCall(MacroAssembler* masm,
774 int argc, 774 const CallOptimization& optimization,
775 Register holder_in, 775 Handle<Map> receiver_map,
776 bool restore_context) { 776 Register receiver,
777 Register scratch_in,
778 int argc,
779 Register* values) {
780 ASSERT(!receiver.is(scratch_in));
781 // Preparing to push, adjust sp.
782 __ Subu(sp, sp, Operand((argc + 1) * kPointerSize));
783 __ sw(receiver, MemOperand(sp, argc * kPointerSize)); // Push receiver.
784 // Write the arguments to stack frame.
785 for (int i = 0; i < argc; i++) {
786 Register arg = values[argc-1-i];
787 ASSERT(!receiver.is(arg));
788 ASSERT(!scratch_in.is(arg));
789 __ sw(arg, MemOperand(sp, (argc-1-i) * kPointerSize)); // Push arg.
790 }
777 ASSERT(optimization.is_simple_api_call()); 791 ASSERT(optimization.is_simple_api_call());
778 792
779 // Abi for CallApiFunctionStub. 793 // Abi for CallApiFunctionStub.
780 Register callee = a0; 794 Register callee = a0;
781 Register call_data = t0; 795 Register call_data = t0;
782 Register holder = a2; 796 Register holder = a2;
783 Register api_function_address = a1; 797 Register api_function_address = a1;
784 798
785 // Put holder in place. 799 // Put holder in place.
786 __ mov(holder, holder_in); 800 CallOptimization::HolderLookup holder_lookup;
801 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
802 receiver_map,
803 &holder_lookup);
804 switch (holder_lookup) {
805 case CallOptimization::kHolderIsReceiver:
806 __ Move(holder, receiver);
807 break;
808 case CallOptimization::kHolderFound:
809 __ li(holder, api_holder);
810 break;
811 case CallOptimization::kHolderNotFound:
812 UNREACHABLE();
813 break;
814 }
787 815
788 Isolate* isolate = masm->isolate(); 816 Isolate* isolate = masm->isolate();
789 Handle<JSFunction> function = optimization.constant_function(); 817 Handle<JSFunction> function = optimization.constant_function();
790 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 818 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
791 Handle<Object> call_data_obj(api_call_info->data(), isolate); 819 Handle<Object> call_data_obj(api_call_info->data(), isolate);
792 820
793 // Put callee in place. 821 // Put callee in place.
794 __ li(callee, function); 822 __ li(callee, function);
795 823
796 bool call_data_undefined = false; 824 bool call_data_undefined = false;
(...skipping 11 matching lines...) Expand all
808 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 836 Address function_address = v8::ToCData<Address>(api_call_info->callback());
809 ApiFunction fun(function_address); 837 ApiFunction fun(function_address);
810 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 838 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
811 ExternalReference ref = 839 ExternalReference ref =
812 ExternalReference(&fun, 840 ExternalReference(&fun,
813 type, 841 type,
814 masm->isolate()); 842 masm->isolate());
815 __ li(api_function_address, Operand(ref)); 843 __ li(api_function_address, Operand(ref));
816 844
817 // Jump to stub. 845 // Jump to stub.
818 CallApiFunctionStub stub(restore_context, call_data_undefined, argc); 846 CallApiFunctionStub stub(true, call_data_undefined, argc);
819 __ TailCallStub(&stub); 847 __ TailCallStub(&stub);
820 } 848 }
821 849
822 850
823 // Generate call to api function.
824 static void GenerateFastApiCall(MacroAssembler* masm,
825 const CallOptimization& optimization,
826 Register receiver,
827 Register scratch,
828 int argc,
829 Register* values) {
830 ASSERT(!receiver.is(scratch));
831 __ push(receiver);
832 // Write the arguments to stack frame.
833 for (int i = 0; i < argc; i++) {
834 Register arg = values[argc-1-i];
835 ASSERT(!receiver.is(arg));
836 ASSERT(!scratch.is(arg));
837 __ push(arg);
838 }
839
840 // Stack now matches JSFunction abi.
841 GenerateFastApiCallBody(masm,
842 optimization,
843 argc,
844 receiver,
845 true);
846 }
847
848
849 class CallInterceptorCompiler BASE_EMBEDDED {
850 public:
851 CallInterceptorCompiler(CallStubCompiler* stub_compiler,
852 Register name)
853 : stub_compiler_(stub_compiler),
854 name_(name) {}
855
856 void Compile(MacroAssembler* masm,
857 Handle<JSObject> object,
858 Handle<JSObject> holder,
859 Handle<Name> name,
860 LookupResult* lookup,
861 Register receiver,
862 Register scratch1,
863 Register scratch2,
864 Register scratch3,
865 Label* miss) {
866 ASSERT(holder->HasNamedInterceptor());
867 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
868
869 // Check that the receiver isn't a smi.
870 __ JumpIfSmi(receiver, miss);
871 CallOptimization optimization(lookup);
872 if (optimization.is_constant_call()) {
873 CompileCacheable(masm, object, receiver, scratch1, scratch2, scratch3,
874 holder, lookup, name, optimization, miss);
875 } else {
876 CompileRegular(masm, object, receiver, scratch1, scratch2, scratch3,
877 name, holder, miss);
878 }
879 }
880
881 private:
882 void CompileCacheable(MacroAssembler* masm,
883 Handle<JSObject> object,
884 Register receiver,
885 Register scratch1,
886 Register scratch2,
887 Register scratch3,
888 Handle<JSObject> interceptor_holder,
889 LookupResult* lookup,
890 Handle<Name> name,
891 const CallOptimization& optimization,
892 Label* miss_label) {
893 ASSERT(optimization.is_constant_call());
894 ASSERT(!lookup->holder()->IsGlobalObject());
895 Counters* counters = masm->isolate()->counters();
896 __ IncrementCounter(counters->call_const_interceptor(), 1,
897 scratch1, scratch2);
898
899 // Check that the maps from receiver to interceptor's holder
900 // haven't changed and thus we can invoke interceptor.
901 Label miss_cleanup;
902 Register holder =
903 stub_compiler_->CheckPrototypes(
904 IC::CurrentTypeOf(object, masm->isolate()), receiver,
905 interceptor_holder, scratch1, scratch2, scratch3,
906 name, miss_label);
907
908 // Invoke an interceptor and if it provides a value,
909 // branch to |regular_invoke|.
910 Label regular_invoke;
911 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2,
912 &regular_invoke);
913
914 // Interceptor returned nothing for this property. Try to use cached
915 // constant function.
916
917 // Check that the maps from interceptor's holder to constant function's
918 // holder haven't changed and thus we can use cached constant function.
919 if (*interceptor_holder != lookup->holder()) {
920 stub_compiler_->CheckPrototypes(
921 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder,
922 handle(lookup->holder()), scratch1, scratch2, scratch3,
923 name, miss_label);
924 }
925
926 Handle<JSFunction> function = optimization.constant_function();
927 __ Move(a0, receiver);
928 stub_compiler_->GenerateJumpFunction(object, function);
929
930 // Invoke a regular function.
931 __ bind(&regular_invoke);
932 }
933
934 void CompileRegular(MacroAssembler* masm,
935 Handle<JSObject> object,
936 Register receiver,
937 Register scratch1,
938 Register scratch2,
939 Register scratch3,
940 Handle<Name> name,
941 Handle<JSObject> interceptor_holder,
942 Label* miss_label) {
943 Register holder =
944 stub_compiler_->CheckPrototypes(
945 IC::CurrentTypeOf(object, masm->isolate()), receiver,
946 interceptor_holder, scratch1, scratch2, scratch3, name, miss_label);
947
948 // Call a runtime function to load the interceptor property.
949 FrameScope scope(masm, StackFrame::INTERNAL);
950 // Save the name_ register across the call.
951 __ push(name_);
952
953 CompileCallLoadPropertyWithInterceptor(
954 masm, receiver, holder, name_, interceptor_holder,
955 IC::kLoadPropertyWithInterceptorForCall);
956
957 // Restore the name_ register.
958 __ pop(name_);
959 // Leave the internal frame.
960 }
961
962 void LoadWithInterceptor(MacroAssembler* masm,
963 Register receiver,
964 Register holder,
965 Handle<JSObject> holder_obj,
966 Register scratch,
967 Label* interceptor_succeeded) {
968 {
969 FrameScope scope(masm, StackFrame::INTERNAL);
970
971 __ Push(receiver, holder, name_);
972 CompileCallLoadPropertyWithInterceptor(
973 masm, receiver, holder, name_, holder_obj,
974 IC::kLoadPropertyWithInterceptorOnly);
975 __ pop(name_);
976 __ pop(holder);
977 __ pop(receiver);
978 }
979 // If interceptor returns no-result sentinel, call the constant function.
980 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex);
981 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch));
982 }
983
984 CallStubCompiler* stub_compiler_;
985 Register name_;
986 };
987
988
989 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 851 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
990 __ Jump(code, RelocInfo::CODE_TARGET); 852 __ Jump(code, RelocInfo::CODE_TARGET);
991 } 853 }
992 854
993 855
994 #undef __ 856 #undef __
995 #define __ ACCESS_MASM(masm()) 857 #define __ ACCESS_MASM(masm())
996 858
997 859
998 Register StubCompiler::CheckPrototypes(Handle<HeapType> type, 860 Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 1057
1196 1058
1197 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 1059 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1198 // Return the constant value. 1060 // Return the constant value.
1199 __ li(v0, value); 1061 __ li(v0, value);
1200 __ Ret(); 1062 __ Ret();
1201 } 1063 }
1202 1064
1203 1065
1204 void LoadStubCompiler::GenerateLoadCallback( 1066 void LoadStubCompiler::GenerateLoadCallback(
1205 const CallOptimization& call_optimization) { 1067 const CallOptimization& call_optimization,
1068 Handle<Map> receiver_map) {
1206 GenerateFastApiCall( 1069 GenerateFastApiCall(
1207 masm(), call_optimization, receiver(), scratch3(), 0, NULL); 1070 masm(), call_optimization, receiver_map,
1071 receiver(), scratch3(), 0, NULL);
1208 } 1072 }
1209 1073
1210 1074
1211 void LoadStubCompiler::GenerateLoadCallback( 1075 void LoadStubCompiler::GenerateLoadCallback(
1212 Register reg, 1076 Register reg,
1213 Handle<ExecutableAccessorInfo> callback) { 1077 Handle<ExecutableAccessorInfo> callback) {
1214 // Build AccessorInfo::args_ list on the stack and push property name below 1078 // Build AccessorInfo::args_ list on the stack and push property name below
1215 // the exit frame to make GC aware of them and store pointers to them. 1079 // the exit frame to make GC aware of them and store pointers to them.
1216 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 1080 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
1217 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 1081 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 PushInterceptorArguments(masm(), receiver(), holder_reg, 1200 PushInterceptorArguments(masm(), receiver(), holder_reg,
1337 this->name(), interceptor_holder); 1201 this->name(), interceptor_holder);
1338 1202
1339 ExternalReference ref = ExternalReference( 1203 ExternalReference ref = ExternalReference(
1340 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); 1204 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate());
1341 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); 1205 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1);
1342 } 1206 }
1343 } 1207 }
1344 1208
1345 1209
1346 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1347 if (kind_ == Code::KEYED_CALL_IC) {
1348 __ Branch(miss, ne, a2, Operand(name));
1349 }
1350 }
1351
1352
1353 void CallStubCompiler::GenerateFunctionCheck(Register function,
1354 Register scratch,
1355 Label* miss) {
1356 __ JumpIfSmi(function, miss);
1357 __ GetObjectType(function, scratch, scratch);
1358 __ Branch(miss, ne, scratch, Operand(JS_FUNCTION_TYPE));
1359 }
1360
1361
1362 void CallStubCompiler::GenerateLoadFunctionFromCell(
1363 Handle<Cell> cell,
1364 Handle<JSFunction> function,
1365 Label* miss) {
1366 // Get the value from the cell.
1367 __ li(a3, Operand(cell));
1368 __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset));
1369
1370 // Check that the cell contains the same function.
1371 if (heap()->InNewSpace(*function)) {
1372 // We can't embed a pointer to a function in new space so we have
1373 // to verify that the shared function info is unchanged. This has
1374 // the nice side effect that multiple closures based on the same
1375 // function can all use this call IC. Before we load through the
1376 // function, we have to verify that it still is a function.
1377 GenerateFunctionCheck(a1, a3, miss);
1378
1379 // Check the shared function info. Make sure it hasn't changed.
1380 __ li(a3, Handle<SharedFunctionInfo>(function->shared()));
1381 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1382 __ Branch(miss, ne, t0, Operand(a3));
1383 } else {
1384 __ Branch(miss, ne, a1, Operand(function));
1385 }
1386 }
1387
1388
1389 void CallStubCompiler::GenerateMissBranch() {
1390 Handle<Code> code =
1391 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1392 kind_,
1393 extra_state());
1394 __ Jump(code, RelocInfo::CODE_TARGET);
1395 }
1396
1397
1398 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1399 Handle<JSObject> holder,
1400 PropertyIndex index,
1401 Handle<Name> name) {
1402 Label miss;
1403
1404 Register reg = HandlerFrontendHeader(
1405 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1406 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder),
1407 index.translate(holder), Representation::Tagged());
1408 GenerateJumpFunction(object, a1, &miss);
1409
1410 HandlerFrontendFooter(&miss);
1411
1412 // Return the generated code.
1413 return GetCode(Code::FAST, name);
1414 }
1415
1416
1417 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 1210 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
1418 Label success; 1211 Label success;
1419 // Check that the object is a boolean. 1212 // Check that the object is a boolean.
1420 __ LoadRoot(at, Heap::kTrueValueRootIndex); 1213 __ LoadRoot(at, Heap::kTrueValueRootIndex);
1421 __ Branch(&success, eq, object, Operand(at)); 1214 __ Branch(&success, eq, object, Operand(at));
1422 __ LoadRoot(at, Heap::kFalseValueRootIndex); 1215 __ LoadRoot(at, Heap::kFalseValueRootIndex);
1423 __ Branch(miss, ne, object, Operand(at)); 1216 __ Branch(miss, ne, object, Operand(at));
1424 __ bind(&success); 1217 __ bind(&success);
1425 } 1218 }
1426 1219
1427 1220
1428 void CallStubCompiler::PatchImplicitReceiver(Handle<Object> object) {
1429 if (object->IsGlobalObject()) {
1430 const int argc = arguments().immediate();
1431 const int receiver_offset = argc * kPointerSize;
1432 __ LoadRoot(a3, Heap::kUndefinedValueRootIndex);
1433 __ sw(a3, MemOperand(sp, receiver_offset));
1434 }
1435 }
1436
1437
1438 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
1439 Handle<JSObject> holder,
1440 Handle<Name> name,
1441 CheckType check,
1442 Label* miss) {
1443 // ----------- S t a t e -------------
1444 // -- a2 : name
1445 // -- ra : return address
1446 // -----------------------------------
1447 GenerateNameCheck(name, miss);
1448
1449 Register reg = a0;
1450
1451 // Get the receiver from the stack.
1452 const int argc = arguments().immediate();
1453 const int receiver_offset = argc * kPointerSize;
1454 __ lw(a0, MemOperand(sp, receiver_offset));
1455
1456 // Check that the receiver isn't a smi.
1457 if (check != NUMBER_CHECK) {
1458 __ JumpIfSmi(a0, miss);
1459 }
1460
1461 // Make sure that it's okay not to patch the on stack receiver
1462 // unless we're doing a receiver map check.
1463 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
1464 switch (check) {
1465 case RECEIVER_MAP_CHECK:
1466 __ IncrementCounter(isolate()->counters()->call_const(), 1, a1, a3);
1467
1468 // Check that the maps haven't changed.
1469 reg = CheckPrototypes(
1470 IC::CurrentTypeOf(object, isolate()),
1471 reg, holder, a1, a3, t0, name, miss);
1472 break;
1473
1474 case STRING_CHECK: {
1475 // Check that the object is a string.
1476 __ GetObjectType(reg, a3, a3);
1477 __ Branch(miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE));
1478 // Check that the maps starting from the prototype haven't changed.
1479 GenerateDirectLoadGlobalFunctionPrototype(
1480 masm(), Context::STRING_FUNCTION_INDEX, a1, miss);
1481 break;
1482 }
1483 case SYMBOL_CHECK: {
1484 // Check that the object is a symbol.
1485 __ GetObjectType(reg, a1, a3);
1486 __ Branch(miss, ne, a3, Operand(SYMBOL_TYPE));
1487 // Check that the maps starting from the prototype haven't changed.
1488 GenerateDirectLoadGlobalFunctionPrototype(
1489 masm(), Context::SYMBOL_FUNCTION_INDEX, a1, miss);
1490 break;
1491 }
1492 case NUMBER_CHECK: {
1493 Label fast;
1494 // Check that the object is a smi or a heap number.
1495 __ JumpIfSmi(reg, &fast);
1496 __ GetObjectType(reg, a3, a3);
1497 __ Branch(miss, ne, a3, Operand(HEAP_NUMBER_TYPE));
1498 __ bind(&fast);
1499 // Check that the maps starting from the prototype haven't changed.
1500 GenerateDirectLoadGlobalFunctionPrototype(
1501 masm(), Context::NUMBER_FUNCTION_INDEX, a1, miss);
1502 break;
1503 }
1504 case BOOLEAN_CHECK: {
1505 GenerateBooleanCheck(reg, miss);
1506
1507 // Check that the maps starting from the prototype haven't changed.
1508 GenerateDirectLoadGlobalFunctionPrototype(
1509 masm(), Context::BOOLEAN_FUNCTION_INDEX, a1, miss);
1510 break;
1511 }
1512 }
1513
1514 if (check != RECEIVER_MAP_CHECK) {
1515 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
1516 reg = CheckPrototypes(
1517 IC::CurrentTypeOf(prototype, isolate()),
1518 a1, holder, a1, a3, t0, name, miss);
1519 }
1520
1521 return reg;
1522 }
1523
1524
1525 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
1526 Register function,
1527 Label* miss) {
1528 ASSERT(function.is(a1));
1529 // Check that the function really is a function.
1530 GenerateFunctionCheck(function, a3, miss);
1531 PatchImplicitReceiver(object);
1532
1533 // Invoke the function.
1534 __ InvokeFunction(a1, arguments(), JUMP_FUNCTION, NullCallWrapper());
1535 }
1536
1537
1538 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
1539 Handle<JSObject> holder,
1540 Handle<Name> name) {
1541 Label miss;
1542
1543 GenerateNameCheck(name, &miss);
1544
1545 // Get the number of arguments.
1546 const int argc = arguments().immediate();
1547 LookupResult lookup(isolate());
1548 LookupPostInterceptor(holder, name, &lookup);
1549
1550 // Get the receiver from the stack.
1551 __ lw(a1, MemOperand(sp, argc * kPointerSize));
1552
1553 CallInterceptorCompiler compiler(this, a2);
1554 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0,
1555 &miss);
1556
1557 // Move returned value, the function to call, to a1.
1558 __ mov(a1, v0);
1559 // Restore receiver.
1560 __ lw(a0, MemOperand(sp, argc * kPointerSize));
1561
1562 GenerateJumpFunction(object, a1, &miss);
1563
1564 HandlerFrontendFooter(&miss);
1565
1566 // Return the generated code.
1567 return GetCode(Code::FAST, name);
1568 }
1569
1570
1571 Handle<Code> CallStubCompiler::CompileCallGlobal(
1572 Handle<JSObject> object,
1573 Handle<GlobalObject> holder,
1574 Handle<PropertyCell> cell,
1575 Handle<JSFunction> function,
1576 Handle<Name> name) {
1577 Label miss;
1578 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1579 // Potentially loads a closure that matches the shared function info of the
1580 // function, rather than function.
1581 GenerateLoadFunctionFromCell(cell, function, &miss);
1582 Counters* counters = isolate()->counters();
1583 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0);
1584 GenerateJumpFunction(object, a1, function);
1585 HandlerFrontendFooter(&miss);
1586
1587 // Return the generated code.
1588 return GetCode(Code::NORMAL, name);
1589 }
1590
1591
1592 Handle<Code> StoreStubCompiler::CompileStoreCallback( 1221 Handle<Code> StoreStubCompiler::CompileStoreCallback(
1593 Handle<JSObject> object, 1222 Handle<JSObject> object,
1594 Handle<JSObject> holder, 1223 Handle<JSObject> holder,
1595 Handle<Name> name, 1224 Handle<Name> name,
1596 Handle<ExecutableAccessorInfo> callback) { 1225 Handle<ExecutableAccessorInfo> callback) {
1597 Register holder_reg = HandlerFrontend( 1226 Register holder_reg = HandlerFrontend(
1598 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); 1227 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
1599 1228
1600 // Stub never generated for non-global objects that require access 1229 // Stub never generated for non-global objects that require access
1601 // checks. 1230 // checks.
1602 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1231 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1603 1232
1604 __ push(receiver()); // Receiver. 1233 __ Push(receiver(), holder_reg); // Receiver.
1605 __ push(holder_reg);
1606 __ li(at, Operand(callback)); // Callback info. 1234 __ li(at, Operand(callback)); // Callback info.
1607 __ push(at); 1235 __ push(at);
1608 __ li(at, Operand(name)); 1236 __ li(at, Operand(name));
1609 __ Push(at, value()); 1237 __ Push(at, value());
1610 1238
1611 // Do tail-call to the runtime system. 1239 // Do tail-call to the runtime system.
1612 ExternalReference store_callback_property = 1240 ExternalReference store_callback_property =
1613 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 1241 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
1614 __ TailCallExternalReference(store_callback_property, 5, 1); 1242 __ TailCallExternalReference(store_callback_property, 5, 1);
1615 1243
1616 // Return the generated code. 1244 // Return the generated code.
1617 return GetCode(kind(), Code::FAST, name); 1245 return GetCode(kind(), Code::FAST, name);
1618 } 1246 }
1619 1247
1620 1248
1621 Handle<Code> StoreStubCompiler::CompileStoreCallback( 1249 Handle<Code> StoreStubCompiler::CompileStoreCallback(
1622 Handle<JSObject> object, 1250 Handle<JSObject> object,
1623 Handle<JSObject> holder, 1251 Handle<JSObject> holder,
1624 Handle<Name> name, 1252 Handle<Name> name,
1625 const CallOptimization& call_optimization) { 1253 const CallOptimization& call_optimization) {
1626 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), 1254 HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
1627 receiver(), holder, name); 1255 receiver(), holder, name);
1628 1256
1629 Register values[] = { value() }; 1257 Register values[] = { value() };
1630 GenerateFastApiCall( 1258 GenerateFastApiCall(
1631 masm(), call_optimization, receiver(), scratch3(), 1, values); 1259 masm(), call_optimization, handle(object->map()),
1260 receiver(), scratch3(), 1, values);
1632 1261
1633 // Return the generated code. 1262 // Return the generated code.
1634 return GetCode(kind(), Code::FAST, name); 1263 return GetCode(kind(), Code::FAST, name);
1635 } 1264 }
1636 1265
1637 1266
1638 #undef __ 1267 #undef __
1639 #define __ ACCESS_MASM(masm) 1268 #define __ ACCESS_MASM(masm)
1640 1269
1641 1270
1642 void StoreStubCompiler::GenerateStoreViaSetter( 1271 void StoreStubCompiler::GenerateStoreViaSetter(
1643 MacroAssembler* masm, 1272 MacroAssembler* masm,
1273 Handle<HeapType> type,
1644 Handle<JSFunction> setter) { 1274 Handle<JSFunction> setter) {
1645 // ----------- S t a t e ------------- 1275 // ----------- S t a t e -------------
1646 // -- a0 : value 1276 // -- a0 : value
1647 // -- a1 : receiver 1277 // -- a1 : receiver
1648 // -- a2 : name 1278 // -- a2 : name
1649 // -- ra : return address 1279 // -- ra : return address
1650 // ----------------------------------- 1280 // -----------------------------------
1651 { 1281 {
1652 FrameScope scope(masm, StackFrame::INTERNAL); 1282 FrameScope scope(masm, StackFrame::INTERNAL);
1283 Register receiver = a1;
1284 Register value = a0;
1653 1285
1654 // Save value register, so we can restore it later. 1286 // Save value register, so we can restore it later.
1655 __ push(a0); 1287 __ push(value);
1656 1288
1657 if (!setter.is_null()) { 1289 if (!setter.is_null()) {
1658 // Call the JavaScript setter with receiver and value on the stack. 1290 // Call the JavaScript setter with receiver and value on the stack.
1659 __ push(a1); 1291 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
1660 __ push(a0); 1292 // Swap in the global receiver.
1293 __ lw(receiver,
1294 FieldMemOperand(
1295 receiver, JSGlobalObject::kGlobalReceiverOffset));
1296 }
1297 __ Push(receiver, value);
1661 ParameterCount actual(1); 1298 ParameterCount actual(1);
1662 ParameterCount expected(setter); 1299 ParameterCount expected(setter);
1663 __ InvokeFunction(setter, expected, actual, 1300 __ InvokeFunction(setter, expected, actual,
1664 CALL_FUNCTION, NullCallWrapper()); 1301 CALL_FUNCTION, NullCallWrapper());
1665 } else { 1302 } else {
1666 // If we generate a global code snippet for deoptimization only, remember 1303 // If we generate a global code snippet for deoptimization only, remember
1667 // the place to continue after deoptimization. 1304 // the place to continue after deoptimization.
1668 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 1305 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
1669 } 1306 }
1670 1307
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 static Register registers[] = { a2, a1, a0, a3, t0, t1 }; 1393 static Register registers[] = { a2, a1, a0, a3, t0, t1 };
1757 return registers; 1394 return registers;
1758 } 1395 }
1759 1396
1760 1397
1761 #undef __ 1398 #undef __
1762 #define __ ACCESS_MASM(masm) 1399 #define __ ACCESS_MASM(masm)
1763 1400
1764 1401
1765 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 1402 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
1403 Handle<HeapType> type,
1766 Register receiver, 1404 Register receiver,
1767 Handle<JSFunction> getter) { 1405 Handle<JSFunction> getter) {
1768 // ----------- S t a t e ------------- 1406 // ----------- S t a t e -------------
1769 // -- a0 : receiver 1407 // -- a0 : receiver
1770 // -- a2 : name 1408 // -- a2 : name
1771 // -- ra : return address 1409 // -- ra : return address
1772 // ----------------------------------- 1410 // -----------------------------------
1773 { 1411 {
1774 FrameScope scope(masm, StackFrame::INTERNAL); 1412 FrameScope scope(masm, StackFrame::INTERNAL);
1775 1413
1776 if (!getter.is_null()) { 1414 if (!getter.is_null()) {
1777 // Call the JavaScript getter with the receiver on the stack. 1415 // Call the JavaScript getter with the receiver on the stack.
1416 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
1417 // Swap in the global receiver.
1418 __ lw(receiver,
1419 FieldMemOperand(
1420 receiver, JSGlobalObject::kGlobalReceiverOffset));
1421 }
1778 __ push(receiver); 1422 __ push(receiver);
1779 ParameterCount actual(0); 1423 ParameterCount actual(0);
1780 ParameterCount expected(getter); 1424 ParameterCount expected(getter);
1781 __ InvokeFunction(getter, expected, actual, 1425 __ InvokeFunction(getter, expected, actual,
1782 CALL_FUNCTION, NullCallWrapper()); 1426 CALL_FUNCTION, NullCallWrapper());
1783 } else { 1427 } else {
1784 // If we generate a global code snippet for deoptimization only, remember 1428 // If we generate a global code snippet for deoptimization only, remember
1785 // the place to continue after deoptimization. 1429 // the place to continue after deoptimization.
1786 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 1430 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
1787 } 1431 }
(...skipping 22 matching lines...) Expand all
1810 // Get the value from the cell. 1454 // Get the value from the cell.
1811 __ li(a3, Operand(cell)); 1455 __ li(a3, Operand(cell));
1812 __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset)); 1456 __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset));
1813 1457
1814 // Check for deleted property if property can actually be deleted. 1458 // Check for deleted property if property can actually be deleted.
1815 if (!is_dont_delete) { 1459 if (!is_dont_delete) {
1816 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1460 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1817 __ Branch(&miss, eq, t0, Operand(at)); 1461 __ Branch(&miss, eq, t0, Operand(at));
1818 } 1462 }
1819 1463
1820 HandlerFrontendFooter(name, &miss);
1821
1822 Counters* counters = isolate()->counters(); 1464 Counters* counters = isolate()->counters();
1823 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); 1465 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
1824 __ Ret(USE_DELAY_SLOT); 1466 __ Ret(USE_DELAY_SLOT);
1825 __ mov(v0, t0); 1467 __ mov(v0, t0);
1826 1468
1469 HandlerFrontendFooter(name, &miss);
1470
1827 // Return the generated code. 1471 // Return the generated code.
1828 return GetCode(kind(), Code::NORMAL, name); 1472 return GetCode(kind(), Code::NORMAL, name);
1829 } 1473 }
1830 1474
1831 1475
1832 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 1476 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
1833 TypeHandleList* types, 1477 TypeHandleList* types,
1834 CodeHandleList* handlers, 1478 CodeHandleList* handlers,
1835 Handle<Name> name, 1479 Handle<Name> name,
1836 Code::StubType type, 1480 Code::StubType type,
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 // ----------------------------------- 1596 // -----------------------------------
1953 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1597 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1954 } 1598 }
1955 1599
1956 1600
1957 #undef __ 1601 #undef __
1958 1602
1959 } } // namespace v8::internal 1603 } } // namespace v8::internal
1960 1604
1961 #endif // V8_TARGET_ARCH_MIPS 1605 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/macro-assembler-mips.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698