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

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

Issue 112863002: Merge bleeding_edge 18021:18297 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years 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') | src/object-observe.js » ('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 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 725 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
726 Label* label, 726 Label* label,
727 Handle<Name> name) { 727 Handle<Name> name) {
728 if (!label->is_unused()) { 728 if (!label->is_unused()) {
729 __ bind(label); 729 __ bind(label);
730 __ li(this->name(), Operand(name)); 730 __ li(this->name(), Operand(name));
731 } 731 }
732 } 732 }
733 733
734 734
735 static void GenerateCallFunction(MacroAssembler* masm,
736 Handle<Object> object,
737 const ParameterCount& arguments,
738 Label* miss,
739 Code::ExtraICState extra_ic_state) {
740 // ----------- S t a t e -------------
741 // -- a0: receiver
742 // -- a1: function to call
743 // -----------------------------------
744 // Check that the function really is a function.
745 __ JumpIfSmi(a1, miss);
746 __ GetObjectType(a1, a3, a3);
747 __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE));
748
749 // Patch the receiver on the stack with the global proxy if
750 // necessary.
751 if (object->IsGlobalObject()) {
752 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
753 __ sw(a3, MemOperand(sp, arguments.immediate() * kPointerSize));
754 }
755
756 // Invoke the function.
757 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
758 ? CALL_AS_FUNCTION
759 : CALL_AS_METHOD;
760 __ InvokeFunction(a1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind);
761 }
762
763
764 static void PushInterceptorArguments(MacroAssembler* masm, 735 static void PushInterceptorArguments(MacroAssembler* masm,
765 Register receiver, 736 Register receiver,
766 Register holder, 737 Register holder,
767 Register name, 738 Register name,
768 Handle<JSObject> holder_obj) { 739 Handle<JSObject> holder_obj) {
769 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); 740 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0);
770 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); 741 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1);
771 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); 742 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2);
772 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); 743 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3);
773 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); 744 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4);
774 __ push(name); 745 __ push(name);
775 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); 746 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
776 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); 747 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor));
777 Register scratch = name; 748 Register scratch = name;
778 __ li(scratch, Operand(interceptor)); 749 __ li(scratch, Operand(interceptor));
779 __ Push(scratch, receiver, holder); 750 __ Push(scratch, receiver, holder);
780 } 751 }
781 752
782 753
783 static void CompileCallLoadPropertyWithInterceptor( 754 static void CompileCallLoadPropertyWithInterceptor(
784 MacroAssembler* masm, 755 MacroAssembler* masm,
785 Register receiver, 756 Register receiver,
786 Register holder, 757 Register holder,
787 Register name, 758 Register name,
788 Handle<JSObject> holder_obj) { 759 Handle<JSObject> holder_obj,
760 IC::UtilityId id) {
789 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 761 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
790 762 __ CallExternalReference(
791 ExternalReference ref = 763 ExternalReference(IC_Utility(id), masm->isolate()),
792 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), 764 StubCache::kInterceptorArgsLength);
793 masm->isolate());
794 __ PrepareCEntryArgs(StubCache::kInterceptorArgsLength);
795 __ PrepareCEntryFunction(ref);
796
797 CEntryStub stub(1);
798 __ CallStub(&stub);
799 } 765 }
800 766
801 767
802 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; 768 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength;
803 769
804 // Reserves space for the extra arguments to API function in the 770 // Reserves space for the extra arguments to API function in the
805 // caller's frame. 771 // caller's frame.
806 // 772 //
807 // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall. 773 // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall.
808 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, 774 static void ReserveSpaceForFastApiCall(MacroAssembler* masm,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 ASSERT(!receiver.is(scratch)); 892 ASSERT(!receiver.is(scratch));
927 893
928 typedef FunctionCallbackArguments FCA; 894 typedef FunctionCallbackArguments FCA;
929 const int stack_space = kFastApiCallArguments + argc + 1; 895 const int stack_space = kFastApiCallArguments + argc + 1;
930 // Assign stack space for the call arguments. 896 // Assign stack space for the call arguments.
931 __ Subu(sp, sp, Operand(stack_space * kPointerSize)); 897 __ Subu(sp, sp, Operand(stack_space * kPointerSize));
932 // Write holder to stack frame. 898 // Write holder to stack frame.
933 __ sw(receiver, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); 899 __ sw(receiver, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
934 // Write receiver to stack frame. 900 // Write receiver to stack frame.
935 int index = stack_space - 1; 901 int index = stack_space - 1;
936 __ sw(receiver, MemOperand(sp, index * kPointerSize)); 902 __ sw(receiver, MemOperand(sp, index-- * kPointerSize));
937 // Write the arguments to stack frame. 903 // Write the arguments to stack frame.
938 for (int i = 0; i < argc; i++) { 904 for (int i = 0; i < argc; i++) {
939 ASSERT(!receiver.is(values[i])); 905 ASSERT(!receiver.is(values[i]));
940 ASSERT(!scratch.is(values[i])); 906 ASSERT(!scratch.is(values[i]));
941 __ sw(receiver, MemOperand(sp, index-- * kPointerSize)); 907 __ sw(values[i], MemOperand(sp, index-- * kPointerSize));
942 } 908 }
943 909
944 GenerateFastApiDirectCall(masm, optimization, argc, true); 910 GenerateFastApiDirectCall(masm, optimization, argc, true);
945 } 911 }
946 912
947 913
948 class CallInterceptorCompiler BASE_EMBEDDED { 914 class CallInterceptorCompiler BASE_EMBEDDED {
949 public: 915 public:
950 CallInterceptorCompiler(StubCompiler* stub_compiler, 916 CallInterceptorCompiler(CallStubCompiler* stub_compiler,
951 const ParameterCount& arguments, 917 const ParameterCount& arguments,
952 Register name, 918 Register name)
953 Code::ExtraICState extra_ic_state)
954 : stub_compiler_(stub_compiler), 919 : stub_compiler_(stub_compiler),
955 arguments_(arguments), 920 arguments_(arguments),
956 name_(name), 921 name_(name) {}
957 extra_ic_state_(extra_ic_state) {}
958 922
959 void Compile(MacroAssembler* masm, 923 void Compile(MacroAssembler* masm,
960 Handle<JSObject> object, 924 Handle<JSObject> object,
961 Handle<JSObject> holder, 925 Handle<JSObject> holder,
962 Handle<Name> name, 926 Handle<Name> name,
963 LookupResult* lookup, 927 LookupResult* lookup,
964 Register receiver, 928 Register receiver,
965 Register scratch1, 929 Register scratch1,
966 Register scratch2, 930 Register scratch2,
967 Register scratch3, 931 Register scratch3,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, 982 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1,
1019 scratch1, scratch2); 983 scratch1, scratch2);
1020 ReserveSpaceForFastApiCall(masm, scratch1); 984 ReserveSpaceForFastApiCall(masm, scratch1);
1021 } 985 }
1022 986
1023 // Check that the maps from receiver to interceptor's holder 987 // Check that the maps from receiver to interceptor's holder
1024 // haven't changed and thus we can invoke interceptor. 988 // haven't changed and thus we can invoke interceptor.
1025 Label miss_cleanup; 989 Label miss_cleanup;
1026 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; 990 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label;
1027 Register holder = 991 Register holder =
1028 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, 992 stub_compiler_->CheckPrototypes(
1029 scratch1, scratch2, scratch3, 993 IC::CurrentTypeOf(object, masm->isolate()), receiver,
1030 name, depth1, miss); 994 interceptor_holder, scratch1, scratch2, scratch3,
995 name, depth1, miss);
1031 996
1032 // Invoke an interceptor and if it provides a value, 997 // Invoke an interceptor and if it provides a value,
1033 // branch to |regular_invoke|. 998 // branch to |regular_invoke|.
1034 Label regular_invoke; 999 Label regular_invoke;
1035 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, 1000 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2,
1036 &regular_invoke); 1001 &regular_invoke);
1037 1002
1038 // Interceptor returned nothing for this property. Try to use cached 1003 // Interceptor returned nothing for this property. Try to use cached
1039 // constant function. 1004 // constant function.
1040 1005
1041 // Check that the maps from interceptor's holder to constant function's 1006 // Check that the maps from interceptor's holder to constant function's
1042 // holder haven't changed and thus we can use cached constant function. 1007 // holder haven't changed and thus we can use cached constant function.
1043 if (*interceptor_holder != lookup->holder()) { 1008 if (*interceptor_holder != lookup->holder()) {
1044 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, 1009 stub_compiler_->CheckPrototypes(
1045 Handle<JSObject>(lookup->holder()), 1010 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder,
1046 scratch1, scratch2, scratch3, 1011 handle(lookup->holder()), scratch1, scratch2, scratch3,
1047 name, depth2, miss); 1012 name, depth2, miss);
1048 } else { 1013 } else {
1049 // CheckPrototypes has a side effect of fetching a 'holder' 1014 // CheckPrototypes has a side effect of fetching a 'holder'
1050 // for API (object which is instanceof for the signature). It's 1015 // for API (object which is instanceof for the signature). It's
1051 // safe to omit it here, as if present, it should be fetched 1016 // safe to omit it here, as if present, it should be fetched
1052 // by the previous CheckPrototypes. 1017 // by the previous CheckPrototypes.
1053 ASSERT(depth2 == kInvalidProtoDepth); 1018 ASSERT(depth2 == kInvalidProtoDepth);
1054 } 1019 }
1055 1020
1056 // Invoke function. 1021 // Invoke function.
1057 if (can_do_fast_api_call) { 1022 if (can_do_fast_api_call) {
1058 GenerateFastApiDirectCall( 1023 GenerateFastApiDirectCall(
1059 masm, optimization, arguments_.immediate(), false); 1024 masm, optimization, arguments_.immediate(), false);
1060 } else { 1025 } else {
1061 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
1062 ? CALL_AS_FUNCTION
1063 : CALL_AS_METHOD;
1064 Handle<JSFunction> function = optimization.constant_function(); 1026 Handle<JSFunction> function = optimization.constant_function();
1065 ParameterCount expected(function); 1027 stub_compiler_->GenerateJumpFunction(object, function);
1066 __ InvokeFunction(function, expected, arguments_,
1067 JUMP_FUNCTION, NullCallWrapper(), call_kind);
1068 } 1028 }
1069 1029
1070 // Deferred code for fast API call case---clean preallocated space. 1030 // Deferred code for fast API call case---clean preallocated space.
1071 if (can_do_fast_api_call) { 1031 if (can_do_fast_api_call) {
1072 __ bind(&miss_cleanup); 1032 __ bind(&miss_cleanup);
1073 FreeSpaceForFastApiCall(masm); 1033 FreeSpaceForFastApiCall(masm);
1074 __ Branch(miss_label); 1034 __ Branch(miss_label);
1075 } 1035 }
1076 1036
1077 // Invoke a regular function. 1037 // Invoke a regular function.
1078 __ bind(&regular_invoke); 1038 __ bind(&regular_invoke);
1079 if (can_do_fast_api_call) { 1039 if (can_do_fast_api_call) {
1080 FreeSpaceForFastApiCall(masm); 1040 FreeSpaceForFastApiCall(masm);
1081 } 1041 }
1082 } 1042 }
1083 1043
1084 void CompileRegular(MacroAssembler* masm, 1044 void CompileRegular(MacroAssembler* masm,
1085 Handle<JSObject> object, 1045 Handle<JSObject> object,
1086 Register receiver, 1046 Register receiver,
1087 Register scratch1, 1047 Register scratch1,
1088 Register scratch2, 1048 Register scratch2,
1089 Register scratch3, 1049 Register scratch3,
1090 Handle<Name> name, 1050 Handle<Name> name,
1091 Handle<JSObject> interceptor_holder, 1051 Handle<JSObject> interceptor_holder,
1092 Label* miss_label) { 1052 Label* miss_label) {
1093 Register holder = 1053 Register holder =
1094 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, 1054 stub_compiler_->CheckPrototypes(
1095 scratch1, scratch2, scratch3, 1055 IC::CurrentTypeOf(object, masm->isolate()), receiver,
1096 name, miss_label); 1056 interceptor_holder, scratch1, scratch2, scratch3, name, miss_label);
1097 1057
1098 // Call a runtime function to load the interceptor property. 1058 // Call a runtime function to load the interceptor property.
1099 FrameScope scope(masm, StackFrame::INTERNAL); 1059 FrameScope scope(masm, StackFrame::INTERNAL);
1100 // Save the name_ register across the call. 1060 // Save the name_ register across the call.
1101 __ push(name_); 1061 __ push(name_);
1102 1062
1103 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); 1063 CompileCallLoadPropertyWithInterceptor(
1064 masm, receiver, holder, name_, interceptor_holder,
1065 IC::kLoadPropertyWithInterceptorForCall);
1104 1066
1105 __ CallExternalReference(
1106 ExternalReference(
1107 IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
1108 masm->isolate()),
1109 StubCache::kInterceptorArgsLength);
1110 // Restore the name_ register. 1067 // Restore the name_ register.
1111 __ pop(name_); 1068 __ pop(name_);
1112 // Leave the internal frame. 1069 // Leave the internal frame.
1113 } 1070 }
1114 1071
1115 void LoadWithInterceptor(MacroAssembler* masm, 1072 void LoadWithInterceptor(MacroAssembler* masm,
1116 Register receiver, 1073 Register receiver,
1117 Register holder, 1074 Register holder,
1118 Handle<JSObject> holder_obj, 1075 Handle<JSObject> holder_obj,
1119 Register scratch, 1076 Register scratch,
1120 Label* interceptor_succeeded) { 1077 Label* interceptor_succeeded) {
1121 { 1078 {
1122 FrameScope scope(masm, StackFrame::INTERNAL); 1079 FrameScope scope(masm, StackFrame::INTERNAL);
1123 1080
1124 __ Push(holder, name_); 1081 __ Push(receiver, holder, name_);
1125 CompileCallLoadPropertyWithInterceptor(masm, 1082 CompileCallLoadPropertyWithInterceptor(
1126 receiver, 1083 masm, receiver, holder, name_, holder_obj,
1127 holder, 1084 IC::kLoadPropertyWithInterceptorOnly);
1128 name_, 1085 __ pop(name_);
1129 holder_obj); 1086 __ pop(holder);
1130 __ pop(name_); // Restore the name. 1087 __ pop(receiver);
1131 __ pop(receiver); // Restore the holder.
1132 } 1088 }
1133 // If interceptor returns no-result sentinel, call the constant function. 1089 // If interceptor returns no-result sentinel, call the constant function.
1134 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); 1090 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex);
1135 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); 1091 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch));
1136 } 1092 }
1137 1093
1138 StubCompiler* stub_compiler_; 1094 CallStubCompiler* stub_compiler_;
1139 const ParameterCount& arguments_; 1095 const ParameterCount& arguments_;
1140 Register name_; 1096 Register name_;
1141 Code::ExtraICState extra_ic_state_;
1142 }; 1097 };
1143 1098
1144 1099
1145 void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm,
1146 Handle<JSObject> object,
1147 Handle<JSObject> holder,
1148 Handle<Name> name,
1149 Register scratch,
1150 Label* miss) {
1151 Handle<JSObject> current = object;
1152 while (!current.is_identical_to(holder)) {
1153 if (current->IsJSGlobalObject()) {
1154 GenerateCheckPropertyCell(masm,
1155 Handle<JSGlobalObject>::cast(current),
1156 name,
1157 scratch,
1158 miss);
1159 }
1160 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
1161 }
1162 }
1163
1164
1165 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 1100 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1166 __ Jump(code, RelocInfo::CODE_TARGET); 1101 __ Jump(code, RelocInfo::CODE_TARGET);
1167 } 1102 }
1168 1103
1169 1104
1170 #undef __ 1105 #undef __
1171 #define __ ACCESS_MASM(masm()) 1106 #define __ ACCESS_MASM(masm())
1172 1107
1173 1108
1174 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1109 Register StubCompiler::CheckPrototypes(Handle<Type> type,
1175 Register object_reg, 1110 Register object_reg,
1176 Handle<JSObject> holder, 1111 Handle<JSObject> holder,
1177 Register holder_reg, 1112 Register holder_reg,
1178 Register scratch1, 1113 Register scratch1,
1179 Register scratch2, 1114 Register scratch2,
1180 Handle<Name> name, 1115 Handle<Name> name,
1181 int save_at_depth, 1116 int save_at_depth,
1182 Label* miss, 1117 Label* miss,
1183 PrototypeCheckType check) { 1118 PrototypeCheckType check) {
1119 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate()));
1184 // Make sure that the type feedback oracle harvests the receiver map. 1120 // Make sure that the type feedback oracle harvests the receiver map.
1185 // TODO(svenpanne) Remove this hack when all ICs are reworked. 1121 // TODO(svenpanne) Remove this hack when all ICs are reworked.
1186 __ li(scratch1, Operand(Handle<Map>(object->map()))); 1122 __ li(scratch1, Operand(receiver_map));
1187 1123
1188 Handle<JSObject> first = object;
1189 // Make sure there's no overlap between holder and object registers. 1124 // Make sure there's no overlap between holder and object registers.
1190 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 1125 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1191 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1126 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1192 && !scratch2.is(scratch1)); 1127 && !scratch2.is(scratch1));
1193 1128
1194 // Keep track of the current object in register reg. 1129 // Keep track of the current object in register reg.
1195 Register reg = object_reg; 1130 Register reg = object_reg;
1196 int depth = 0; 1131 int depth = 0;
1197 1132
1198 typedef FunctionCallbackArguments FCA; 1133 typedef FunctionCallbackArguments FCA;
1199 if (save_at_depth == depth) { 1134 if (save_at_depth == depth) {
1200 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); 1135 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
1201 } 1136 }
1202 1137
1203 // Check the maps in the prototype chain. 1138 Handle<JSObject> current = Handle<JSObject>::null();
1204 // Traverse the prototype chain from the object and do map checks. 1139 if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
1205 Handle<JSObject> current = object; 1140 Handle<JSObject> prototype = Handle<JSObject>::null();
1206 while (!current.is_identical_to(holder)) { 1141 Handle<Map> current_map = receiver_map;
1142 Handle<Map> holder_map(holder->map());
1143 // Traverse the prototype chain and check the maps in the prototype chain for
1144 // fast and global objects or do negative lookup for normal objects.
1145 while (!current_map.is_identical_to(holder_map)) {
1207 ++depth; 1146 ++depth;
1208 1147
1209 // Only global objects and objects that do not require access 1148 // Only global objects and objects that do not require access
1210 // checks are allowed in stubs. 1149 // checks are allowed in stubs.
1211 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); 1150 ASSERT(current_map->IsJSGlobalProxyMap() ||
1151 !current_map->is_access_check_needed());
1212 1152
1213 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); 1153 prototype = handle(JSObject::cast(current_map->prototype()));
1214 if (!current->HasFastProperties() && 1154 if (current_map->is_dictionary_map() &&
1215 !current->IsJSGlobalObject() && 1155 !current_map->IsJSGlobalObjectMap() &&
1216 !current->IsJSGlobalProxy()) { 1156 !current_map->IsJSGlobalProxyMap()) {
1217 if (!name->IsUniqueName()) { 1157 if (!name->IsUniqueName()) {
1218 ASSERT(name->IsString()); 1158 ASSERT(name->IsString());
1219 name = factory()->InternalizeString(Handle<String>::cast(name)); 1159 name = factory()->InternalizeString(Handle<String>::cast(name));
1220 } 1160 }
1221 ASSERT(current->property_dictionary()->FindEntry(*name) == 1161 ASSERT(current.is_null() ||
1162 current->property_dictionary()->FindEntry(*name) ==
1222 NameDictionary::kNotFound); 1163 NameDictionary::kNotFound);
1223 1164
1224 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, 1165 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
1225 scratch1, scratch2); 1166 scratch1, scratch2);
1226 1167
1227 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 1168 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1228 reg = holder_reg; // From now on the object will be in holder_reg. 1169 reg = holder_reg; // From now on the object will be in holder_reg.
1229 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 1170 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
1230 } else { 1171 } else {
1231 Register map_reg = scratch1; 1172 Register map_reg = scratch1;
1232 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { 1173 if (depth != 1 || check == CHECK_ALL_MAPS) {
1233 Handle<Map> current_map(current->map());
1234 // CheckMap implicitly loads the map of |reg| into |map_reg|. 1174 // CheckMap implicitly loads the map of |reg| into |map_reg|.
1235 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); 1175 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK);
1236 } else { 1176 } else {
1237 __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); 1177 __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
1238 } 1178 }
1179
1239 // Check access rights to the global object. This has to happen after 1180 // Check access rights to the global object. This has to happen after
1240 // the map check so that we know that the object is actually a global 1181 // the map check so that we know that the object is actually a global
1241 // object. 1182 // object.
1242 if (current->IsJSGlobalProxy()) { 1183 if (current_map->IsJSGlobalProxyMap()) {
1243 __ CheckAccessGlobalProxy(reg, scratch2, miss); 1184 __ CheckAccessGlobalProxy(reg, scratch2, miss);
1185 } else if (current_map->IsJSGlobalObjectMap()) {
1186 GenerateCheckPropertyCell(
1187 masm(), Handle<JSGlobalObject>::cast(current), name,
1188 scratch2, miss);
1244 } 1189 }
1190
1245 reg = holder_reg; // From now on the object will be in holder_reg. 1191 reg = holder_reg; // From now on the object will be in holder_reg.
1246 1192
1247 if (heap()->InNewSpace(*prototype)) { 1193 if (heap()->InNewSpace(*prototype)) {
1248 // The prototype is in new space; we cannot store a reference to it 1194 // The prototype is in new space; we cannot store a reference to it
1249 // in the code. Load it from the map. 1195 // in the code. Load it from the map.
1250 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); 1196 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
1251 } else { 1197 } else {
1252 // The prototype is in old space; load it directly. 1198 // The prototype is in old space; load it directly.
1253 __ li(reg, Operand(prototype)); 1199 __ li(reg, Operand(prototype));
1254 } 1200 }
1255 } 1201 }
1256 1202
1257 if (save_at_depth == depth) { 1203 if (save_at_depth == depth) {
1258 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); 1204 __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
1259 } 1205 }
1260 1206
1261 // Go to the next object in the prototype chain. 1207 // Go to the next object in the prototype chain.
1262 current = prototype; 1208 current = prototype;
1209 current_map = handle(current->map());
1263 } 1210 }
1264 1211
1265 // Log the check depth. 1212 // Log the check depth.
1266 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1213 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1267 1214
1268 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { 1215 if (depth != 0 || check == CHECK_ALL_MAPS) {
1269 // Check the holder map. 1216 // Check the holder map.
1270 __ CheckMap(reg, scratch1, Handle<Map>(holder->map()), miss, 1217 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK);
1271 DONT_DO_SMI_CHECK);
1272 } 1218 }
1273 1219
1274 // Perform security check for access to the global object. 1220 // Perform security check for access to the global object.
1275 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1221 ASSERT(current_map->IsJSGlobalProxyMap() ||
1276 if (holder->IsJSGlobalProxy()) { 1222 !current_map->is_access_check_needed());
1223 if (current_map->IsJSGlobalProxyMap()) {
1277 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1224 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1278 } 1225 }
1279 1226
1280 // If we've skipped any global objects, it's not enough to verify that
1281 // their maps haven't changed. We also need to check that the property
1282 // cell for the property is still empty.
1283 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1284
1285 // Return the register containing the holder. 1227 // Return the register containing the holder.
1286 return reg; 1228 return reg;
1287 } 1229 }
1288 1230
1289 1231
1290 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 1232 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1291 if (!miss->is_unused()) { 1233 if (!miss->is_unused()) {
1292 Label success; 1234 Label success;
1293 __ Branch(&success); 1235 __ Branch(&success);
1294 __ bind(miss); 1236 __ bind(miss);
1295 TailCallBuiltin(masm(), MissBuiltin(kind())); 1237 TailCallBuiltin(masm(), MissBuiltin(kind()));
1296 __ bind(&success); 1238 __ bind(&success);
1297 } 1239 }
1298 } 1240 }
1299 1241
1300 1242
1301 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 1243 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1302 if (!miss->is_unused()) { 1244 if (!miss->is_unused()) {
1303 Label success; 1245 Label success;
1304 __ Branch(&success); 1246 __ Branch(&success);
1305 GenerateRestoreName(masm(), miss, name); 1247 GenerateRestoreName(masm(), miss, name);
1306 TailCallBuiltin(masm(), MissBuiltin(kind())); 1248 TailCallBuiltin(masm(), MissBuiltin(kind()));
1307 __ bind(&success); 1249 __ bind(&success);
1308 } 1250 }
1309 } 1251 }
1310 1252
1311 1253
1312 Register LoadStubCompiler::CallbackHandlerFrontend( 1254 Register LoadStubCompiler::CallbackHandlerFrontend(
1313 Handle<Object> object, 1255 Handle<Type> type,
1314 Register object_reg, 1256 Register object_reg,
1315 Handle<JSObject> holder, 1257 Handle<JSObject> holder,
1316 Handle<Name> name, 1258 Handle<Name> name,
1317 Handle<Object> callback) { 1259 Handle<Object> callback) {
1318 Label miss; 1260 Label miss;
1319 1261
1320 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1262 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss);
1321 1263
1322 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 1264 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
1323 ASSERT(!reg.is(scratch2())); 1265 ASSERT(!reg.is(scratch2()));
1324 ASSERT(!reg.is(scratch3())); 1266 ASSERT(!reg.is(scratch3()));
1325 ASSERT(!reg.is(scratch4())); 1267 ASSERT(!reg.is(scratch4()));
1326 1268
1327 // Load the properties dictionary. 1269 // Load the properties dictionary.
1328 Register dictionary = scratch4(); 1270 Register dictionary = scratch4();
1329 __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); 1271 __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset));
1330 1272
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 { 1443 {
1502 FrameScope frame_scope(masm(), StackFrame::INTERNAL); 1444 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
1503 if (must_preserve_receiver_reg) { 1445 if (must_preserve_receiver_reg) {
1504 __ Push(receiver(), holder_reg, this->name()); 1446 __ Push(receiver(), holder_reg, this->name());
1505 } else { 1447 } else {
1506 __ Push(holder_reg, this->name()); 1448 __ Push(holder_reg, this->name());
1507 } 1449 }
1508 // Invoke an interceptor. Note: map checks from receiver to 1450 // Invoke an interceptor. Note: map checks from receiver to
1509 // interceptor's holder has been compiled before (see a caller 1451 // interceptor's holder has been compiled before (see a caller
1510 // of this method). 1452 // of this method).
1511 CompileCallLoadPropertyWithInterceptor(masm(), 1453 CompileCallLoadPropertyWithInterceptor(
1512 receiver(), 1454 masm(), receiver(), holder_reg, this->name(), interceptor_holder,
1513 holder_reg, 1455 IC::kLoadPropertyWithInterceptorOnly);
1514 this->name(), 1456
1515 interceptor_holder);
1516 // Check if interceptor provided a value for property. If it's 1457 // Check if interceptor provided a value for property. If it's
1517 // the case, return immediately. 1458 // the case, return immediately.
1518 Label interceptor_failed; 1459 Label interceptor_failed;
1519 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 1460 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
1520 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1())); 1461 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1()));
1521 frame_scope.GenerateLeaveFrame(); 1462 frame_scope.GenerateLeaveFrame();
1522 __ Ret(); 1463 __ Ret();
1523 1464
1524 __ bind(&interceptor_failed); 1465 __ bind(&interceptor_failed);
1525 __ pop(this->name()); 1466 __ pop(this->name());
(...skipping 17 matching lines...) Expand all
1543 } 1484 }
1544 1485
1545 1486
1546 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1487 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1547 if (kind_ == Code::KEYED_CALL_IC) { 1488 if (kind_ == Code::KEYED_CALL_IC) {
1548 __ Branch(miss, ne, a2, Operand(name)); 1489 __ Branch(miss, ne, a2, Operand(name));
1549 } 1490 }
1550 } 1491 }
1551 1492
1552 1493
1553 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, 1494 void CallStubCompiler::GenerateFunctionCheck(Register function,
1554 Handle<JSObject> holder, 1495 Register scratch,
1555 Handle<Name> name, 1496 Label* miss) {
1556 Label* miss) { 1497 __ JumpIfSmi(function, miss);
1557 ASSERT(holder->IsGlobalObject()); 1498 __ GetObjectType(function, scratch, scratch);
1558 1499 __ Branch(miss, ne, scratch, Operand(JS_FUNCTION_TYPE));
1559 // Get the number of arguments.
1560 const int argc = arguments().immediate();
1561
1562 // Get the receiver from the stack.
1563 __ lw(a0, MemOperand(sp, argc * kPointerSize));
1564
1565 // Check that the maps haven't changed.
1566 __ JumpIfSmi(a0, miss);
1567 CheckPrototypes(object, a0, holder, a3, a1, t0, name, miss);
1568 } 1500 }
1569 1501
1570 1502
1571 void CallStubCompiler::GenerateLoadFunctionFromCell( 1503 void CallStubCompiler::GenerateLoadFunctionFromCell(
1572 Handle<Cell> cell, 1504 Handle<Cell> cell,
1573 Handle<JSFunction> function, 1505 Handle<JSFunction> function,
1574 Label* miss) { 1506 Label* miss) {
1575 // Get the value from the cell. 1507 // Get the value from the cell.
1576 __ li(a3, Operand(cell)); 1508 __ li(a3, Operand(cell));
1577 __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset)); 1509 __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset));
1578 1510
1579 // Check that the cell contains the same function. 1511 // Check that the cell contains the same function.
1580 if (heap()->InNewSpace(*function)) { 1512 if (heap()->InNewSpace(*function)) {
1581 // We can't embed a pointer to a function in new space so we have 1513 // We can't embed a pointer to a function in new space so we have
1582 // to verify that the shared function info is unchanged. This has 1514 // to verify that the shared function info is unchanged. This has
1583 // the nice side effect that multiple closures based on the same 1515 // the nice side effect that multiple closures based on the same
1584 // function can all use this call IC. Before we load through the 1516 // function can all use this call IC. Before we load through the
1585 // function, we have to verify that it still is a function. 1517 // function, we have to verify that it still is a function.
1586 __ JumpIfSmi(a1, miss); 1518 GenerateFunctionCheck(a1, a3, miss);
1587 __ GetObjectType(a1, a3, a3);
1588 __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE));
1589 1519
1590 // Check the shared function info. Make sure it hasn't changed. 1520 // Check the shared function info. Make sure it hasn't changed.
1591 __ li(a3, Handle<SharedFunctionInfo>(function->shared())); 1521 __ li(a3, Handle<SharedFunctionInfo>(function->shared()));
1592 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 1522 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1593 __ Branch(miss, ne, t0, Operand(a3)); 1523 __ Branch(miss, ne, t0, Operand(a3));
1594 } else { 1524 } else {
1595 __ Branch(miss, ne, a1, Operand(function)); 1525 __ Branch(miss, ne, a1, Operand(function));
1596 } 1526 }
1597 } 1527 }
1598 1528
1599 1529
1600 void CallStubCompiler::GenerateMissBranch() { 1530 void CallStubCompiler::GenerateMissBranch() {
1601 Handle<Code> code = 1531 Handle<Code> code =
1602 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 1532 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1603 kind_, 1533 kind_,
1604 extra_state_); 1534 extra_state());
1605 __ Jump(code, RelocInfo::CODE_TARGET); 1535 __ Jump(code, RelocInfo::CODE_TARGET);
1606 } 1536 }
1607 1537
1608 1538
1609 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1539 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1610 Handle<JSObject> holder, 1540 Handle<JSObject> holder,
1611 PropertyIndex index, 1541 PropertyIndex index,
1612 Handle<Name> name) { 1542 Handle<Name> name) {
1613 // ----------- S t a t e -------------
1614 // -- a2 : name
1615 // -- ra : return address
1616 // -----------------------------------
1617 Label miss; 1543 Label miss;
1618 1544
1619 GenerateNameCheck(name, &miss); 1545 Register reg = HandlerFrontendHeader(
1620 1546 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1621 const int argc = arguments().immediate();
1622
1623 // Get the receiver of the function from the stack into a0.
1624 __ lw(a0, MemOperand(sp, argc * kPointerSize));
1625 // Check that the receiver isn't a smi.
1626 __ JumpIfSmi(a0, &miss, t0);
1627
1628 // Do the right check and compute the holder register.
1629 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss);
1630 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder), 1547 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder),
1631 index.translate(holder), Representation::Tagged()); 1548 index.translate(holder), Representation::Tagged());
1549 GenerateJumpFunction(object, a1, &miss);
1632 1550
1633 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); 1551 HandlerFrontendFooter(&miss);
1634
1635 // Handle call cache miss.
1636 __ bind(&miss);
1637 GenerateMissBranch();
1638 1552
1639 // Return the generated code. 1553 // Return the generated code.
1640 return GetCode(Code::FAST, name); 1554 return GetCode(Code::FAST, name);
1641 } 1555 }
1642 1556
1643 1557
1644 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1558 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1645 Handle<Object> object, 1559 Handle<Object> object,
1646 Handle<JSObject> holder, 1560 Handle<JSObject> holder,
1647 Handle<Cell> cell, 1561 Handle<Cell> cell,
1648 Handle<JSFunction> function, 1562 Handle<JSFunction> function,
1649 Handle<String> name, 1563 Handle<String> name,
1650 Code::StubType type) { 1564 Code::StubType type) {
1651 Label miss; 1565 Label miss;
1652 1566
1653 // Check that function is still array. 1567 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1654 const int argc = arguments().immediate(); 1568 if (!cell.is_null()) {
1655 GenerateNameCheck(name, &miss);
1656 Register receiver = a1;
1657
1658 if (cell.is_null()) {
1659 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
1660
1661 // Check that the receiver isn't a smi.
1662 __ JumpIfSmi(receiver, &miss);
1663
1664 // Check that the maps haven't changed.
1665 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, a3, a0,
1666 t0, name, &miss);
1667 } else {
1668 ASSERT(cell->value() == *function); 1569 ASSERT(cell->value() == *function);
1669 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1670 &miss);
1671 GenerateLoadFunctionFromCell(cell, function, &miss); 1570 GenerateLoadFunctionFromCell(cell, function, &miss);
1672 } 1571 }
1673 1572
1674 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1573 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1675 site->SetElementsKind(GetInitialFastElementsKind()); 1574 site->SetElementsKind(GetInitialFastElementsKind());
1676 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1575 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1576 const int argc = arguments().immediate();
1677 __ li(a0, Operand(argc)); 1577 __ li(a0, Operand(argc));
1678 __ li(a2, Operand(site_feedback_cell)); 1578 __ li(a2, Operand(site_feedback_cell));
1679 __ li(a1, Operand(function)); 1579 __ li(a1, Operand(function));
1680 1580
1681 ArrayConstructorStub stub(isolate()); 1581 ArrayConstructorStub stub(isolate());
1682 __ TailCallStub(&stub); 1582 __ TailCallStub(&stub);
1683 1583
1684 __ bind(&miss); 1584 HandlerFrontendFooter(&miss);
1685 GenerateMissBranch();
1686 1585
1687 // Return the generated code. 1586 // Return the generated code.
1688 return GetCode(type, name); 1587 return GetCode(type, name);
1689 } 1588 }
1690 1589
1691 1590
1692 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1591 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1693 Handle<Object> object, 1592 Handle<Object> object,
1694 Handle<JSObject> holder, 1593 Handle<JSObject> holder,
1695 Handle<Cell> cell, 1594 Handle<Cell> cell,
1696 Handle<JSFunction> function, 1595 Handle<JSFunction> function,
1697 Handle<String> name, 1596 Handle<String> name,
1698 Code::StubType type) { 1597 Code::StubType type) {
1699 // ----------- S t a t e ------------- 1598 // If object is not an array or is observed or sealed, bail out to regular
1700 // -- a2 : name 1599 // call.
1701 // -- ra : return address
1702 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1703 // -- ...
1704 // -- sp[argc * 4] : receiver
1705 // -----------------------------------
1706
1707 // If object is not an array or is observed, bail out to regular call.
1708 if (!object->IsJSArray() || 1600 if (!object->IsJSArray() ||
1709 !cell.is_null() || 1601 !cell.is_null() ||
1710 Handle<JSArray>::cast(object)->map()->is_observed()) { 1602 Handle<JSArray>::cast(object)->map()->is_observed() ||
1603 !Handle<JSArray>::cast(object)->map()->is_extensible()) {
1711 return Handle<Code>::null(); 1604 return Handle<Code>::null();
1712 } 1605 }
1713 1606
1714 Label miss; 1607 Label miss;
1608 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1609 Register receiver = a0;
1610 Register scratch = a1;
1715 1611
1716 GenerateNameCheck(name, &miss);
1717
1718 Register receiver = a1;
1719
1720 // Get the receiver from the stack.
1721 const int argc = arguments().immediate(); 1612 const int argc = arguments().immediate();
1722 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
1723
1724 // Check that the receiver isn't a smi.
1725 __ JumpIfSmi(receiver, &miss);
1726
1727 // Check that the maps haven't changed.
1728 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, a3, v0, t0,
1729 name, &miss);
1730 1613
1731 if (argc == 0) { 1614 if (argc == 0) {
1732 // Nothing to do, just return the length. 1615 // Nothing to do, just return the length.
1733 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1616 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1734 __ DropAndRet(argc + 1); 1617 __ DropAndRet(argc + 1);
1735 } else { 1618 } else {
1736 Label call_builtin; 1619 Label call_builtin;
1737 if (argc == 1) { // Otherwise fall through to call the builtin. 1620 if (argc == 1) { // Otherwise fall through to call the builtin.
1738 Label attempt_to_grow_elements, with_write_barrier, check_double; 1621 Label attempt_to_grow_elements, with_write_barrier, check_double;
1739 1622
1740 Register elements = t2; 1623 Register elements = t2;
1741 Register end_elements = t1; 1624 Register end_elements = t1;
1742 // Get the elements array of the object. 1625 // Get the elements array of the object.
1743 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 1626 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
1744 1627
1745 // Check that the elements are in fast mode and writable. 1628 // Check that the elements are in fast mode and writable.
1746 __ CheckMap(elements, 1629 __ CheckMap(elements,
1747 v0, 1630 scratch,
1748 Heap::kFixedArrayMapRootIndex, 1631 Heap::kFixedArrayMapRootIndex,
1749 &check_double, 1632 &check_double,
1750 DONT_DO_SMI_CHECK); 1633 DONT_DO_SMI_CHECK);
1751 1634
1752 // Get the array's length into v0 and calculate new length. 1635 // Get the array's length into scratch and calculate new length.
1753 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1636 __ lw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1754 STATIC_ASSERT(kSmiTagSize == 1); 1637 STATIC_ASSERT(kSmiTagSize == 1);
1755 STATIC_ASSERT(kSmiTag == 0); 1638 STATIC_ASSERT(kSmiTag == 0);
1756 __ Addu(v0, v0, Operand(Smi::FromInt(argc))); 1639 __ Addu(scratch, scratch, Operand(Smi::FromInt(argc)));
1757 1640
1758 // Get the elements' length. 1641 // Get the elements' length.
1759 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1642 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
1760 1643
1761 // Check if we could survive without allocation. 1644 // Check if we could survive without allocation.
1762 __ Branch(&attempt_to_grow_elements, gt, v0, Operand(t0)); 1645 __ Branch(&attempt_to_grow_elements, gt, scratch, Operand(t0));
1763 1646
1764 // Check if value is a smi. 1647 // Check if value is a smi.
1765 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize)); 1648 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
1766 __ JumpIfNotSmi(t0, &with_write_barrier); 1649 __ JumpIfNotSmi(t0, &with_write_barrier);
1767 1650
1768 // Save new length. 1651 // Save new length.
1769 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1652 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1770 1653
1771 // Store the value. 1654 // Store the value.
1772 // We may need a register containing the address end_elements below, 1655 // We may need a register containing the address end_elements below,
1773 // so write back the value in end_elements. 1656 // so write back the value in end_elements.
1774 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); 1657 __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
1775 __ Addu(end_elements, elements, end_elements); 1658 __ Addu(end_elements, elements, end_elements);
1776 const int kEndElementsOffset = 1659 const int kEndElementsOffset =
1777 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; 1660 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
1778 __ Addu(end_elements, end_elements, kEndElementsOffset); 1661 __ Addu(end_elements, end_elements, kEndElementsOffset);
1779 __ sw(t0, MemOperand(end_elements)); 1662 __ sw(t0, MemOperand(end_elements));
1780 1663
1781 // Check for a smi. 1664 // Check for a smi.
1665 __ mov(v0, scratch);
1782 __ DropAndRet(argc + 1); 1666 __ DropAndRet(argc + 1);
1783 1667
1784 __ bind(&check_double); 1668 __ bind(&check_double);
1785 1669
1786 // Check that the elements are in fast mode and writable. 1670 // Check that the elements are in fast mode and writable.
1787 __ CheckMap(elements, 1671 __ CheckMap(elements,
1788 a0, 1672 scratch,
1789 Heap::kFixedDoubleArrayMapRootIndex, 1673 Heap::kFixedDoubleArrayMapRootIndex,
1790 &call_builtin, 1674 &call_builtin,
1791 DONT_DO_SMI_CHECK); 1675 DONT_DO_SMI_CHECK);
1792 1676
1793 // Get the array's length into v0 and calculate new length. 1677 // Get the array's length into scratch and calculate new length.
1794 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1678 __ lw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1795 STATIC_ASSERT(kSmiTagSize == 1); 1679 STATIC_ASSERT(kSmiTagSize == 1);
1796 STATIC_ASSERT(kSmiTag == 0); 1680 STATIC_ASSERT(kSmiTag == 0);
1797 __ Addu(v0, v0, Operand(Smi::FromInt(argc))); 1681 __ Addu(scratch, scratch, Operand(Smi::FromInt(argc)));
1798 1682
1799 // Get the elements' length. 1683 // Get the elements' length.
1800 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1684 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
1801 1685
1802 // Check if we could survive without allocation. 1686 // Check if we could survive without allocation.
1803 __ Branch(&call_builtin, gt, v0, Operand(t0)); 1687 __ Branch(&call_builtin, gt, scratch, Operand(t0));
1804 1688
1805 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize)); 1689 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
1806 __ StoreNumberToDoubleElements( 1690 __ StoreNumberToDoubleElements(
1807 t0, v0, elements, a3, t1, a2, 1691 t0, scratch, elements, a3, t1, a2,
1808 &call_builtin, argc * kDoubleSize); 1692 &call_builtin, argc * kDoubleSize);
1809 1693
1810 // Save new length. 1694 // Save new length.
1811 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1695 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1812 1696
1813 // Check for a smi. 1697 __ mov(v0, scratch);
1814 __ DropAndRet(argc + 1); 1698 __ DropAndRet(argc + 1);
1815 1699
1816 __ bind(&with_write_barrier); 1700 __ bind(&with_write_barrier);
1817 1701
1818 __ lw(a3, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1702 __ lw(a3, FieldMemOperand(receiver, HeapObject::kMapOffset));
1819 1703
1820 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) { 1704 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) {
1821 Label fast_object, not_fast_object; 1705 Label fast_object, not_fast_object;
1822 __ CheckFastObjectElements(a3, t3, &not_fast_object); 1706 __ CheckFastObjectElements(a3, t3, &not_fast_object);
1823 __ jmp(&fast_object); 1707 __ jmp(&fast_object);
(...skipping 29 matching lines...) Expand all
1853 ElementsTransitionGenerator:: 1737 ElementsTransitionGenerator::
1854 GenerateMapChangeElementsTransition(masm(), 1738 GenerateMapChangeElementsTransition(masm(),
1855 DONT_TRACK_ALLOCATION_SITE, 1739 DONT_TRACK_ALLOCATION_SITE,
1856 NULL); 1740 NULL);
1857 __ bind(&fast_object); 1741 __ bind(&fast_object);
1858 } else { 1742 } else {
1859 __ CheckFastObjectElements(a3, a3, &call_builtin); 1743 __ CheckFastObjectElements(a3, a3, &call_builtin);
1860 } 1744 }
1861 1745
1862 // Save new length. 1746 // Save new length.
1863 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1747 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1864 1748
1865 // Store the value. 1749 // Store the value.
1866 // We may need a register containing the address end_elements below, 1750 // We may need a register containing the address end_elements below,
1867 // so write back the value in end_elements. 1751 // so write back the value in end_elements.
1868 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); 1752 __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
1869 __ Addu(end_elements, elements, end_elements); 1753 __ Addu(end_elements, elements, end_elements);
1870 __ Addu(end_elements, end_elements, kEndElementsOffset); 1754 __ Addu(end_elements, end_elements, kEndElementsOffset);
1871 __ sw(t0, MemOperand(end_elements)); 1755 __ sw(t0, MemOperand(end_elements));
1872 1756
1873 __ RecordWrite(elements, 1757 __ RecordWrite(elements,
1874 end_elements, 1758 end_elements,
1875 t0, 1759 t0,
1876 kRAHasNotBeenSaved, 1760 kRAHasNotBeenSaved,
1877 kDontSaveFPRegs, 1761 kDontSaveFPRegs,
1878 EMIT_REMEMBERED_SET, 1762 EMIT_REMEMBERED_SET,
1879 OMIT_SMI_CHECK); 1763 OMIT_SMI_CHECK);
1764 __ mov(v0, scratch);
1880 __ DropAndRet(argc + 1); 1765 __ DropAndRet(argc + 1);
1881 1766
1882 __ bind(&attempt_to_grow_elements); 1767 __ bind(&attempt_to_grow_elements);
1883 // v0: array's length + 1. 1768 // scratch: array's length + 1.
1884 // t0: elements' length. 1769 // t0: elements' length.
1885 1770
1886 if (!FLAG_inline_new) { 1771 if (!FLAG_inline_new) {
1887 __ Branch(&call_builtin); 1772 __ Branch(&call_builtin);
1888 } 1773 }
1889 1774
1890 __ lw(a2, MemOperand(sp, (argc - 1) * kPointerSize)); 1775 __ lw(a2, MemOperand(sp, (argc - 1) * kPointerSize));
1891 // Growing elements that are SMI-only requires special handling in case 1776 // Growing elements that are SMI-only requires special handling in case
1892 // the new element is non-Smi. For now, delegate to the builtin. 1777 // the new element is non-Smi. For now, delegate to the builtin.
1893 Label no_fast_elements_check; 1778 Label no_fast_elements_check;
1894 __ JumpIfSmi(a2, &no_fast_elements_check); 1779 __ JumpIfSmi(a2, &no_fast_elements_check);
1895 __ lw(t3, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1780 __ lw(t3, FieldMemOperand(receiver, HeapObject::kMapOffset));
1896 __ CheckFastObjectElements(t3, t3, &call_builtin); 1781 __ CheckFastObjectElements(t3, t3, &call_builtin);
1897 __ bind(&no_fast_elements_check); 1782 __ bind(&no_fast_elements_check);
1898 1783
1899 ExternalReference new_space_allocation_top = 1784 ExternalReference new_space_allocation_top =
1900 ExternalReference::new_space_allocation_top_address(isolate()); 1785 ExternalReference::new_space_allocation_top_address(isolate());
1901 ExternalReference new_space_allocation_limit = 1786 ExternalReference new_space_allocation_limit =
1902 ExternalReference::new_space_allocation_limit_address(isolate()); 1787 ExternalReference::new_space_allocation_limit_address(isolate());
1903 1788
1904 const int kAllocationDelta = 4; 1789 const int kAllocationDelta = 4;
1905 // Load top and check if it is the end of elements. 1790 // Load top and check if it is the end of elements.
1906 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); 1791 __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
1907 __ Addu(end_elements, elements, end_elements); 1792 __ Addu(end_elements, elements, end_elements);
1908 __ Addu(end_elements, end_elements, Operand(kEndElementsOffset)); 1793 __ Addu(end_elements, end_elements, Operand(kEndElementsOffset));
1909 __ li(t3, Operand(new_space_allocation_top)); 1794 __ li(t3, Operand(new_space_allocation_top));
1910 __ lw(a3, MemOperand(t3)); 1795 __ lw(a3, MemOperand(t3));
1911 __ Branch(&call_builtin, ne, end_elements, Operand(a3)); 1796 __ Branch(&call_builtin, ne, end_elements, Operand(a3));
1912 1797
1913 __ li(t5, Operand(new_space_allocation_limit)); 1798 __ li(t5, Operand(new_space_allocation_limit));
1914 __ lw(t5, MemOperand(t5)); 1799 __ lw(t5, MemOperand(t5));
1915 __ Addu(a3, a3, Operand(kAllocationDelta * kPointerSize)); 1800 __ Addu(a3, a3, Operand(kAllocationDelta * kPointerSize));
1916 __ Branch(&call_builtin, hi, a3, Operand(t5)); 1801 __ Branch(&call_builtin, hi, a3, Operand(t5));
1917 1802
1918 // We fit and could grow elements. 1803 // We fit and could grow elements.
1919 // Update new_space_allocation_top. 1804 // Update new_space_allocation_top.
1920 __ sw(a3, MemOperand(t3)); 1805 __ sw(a3, MemOperand(t3));
1921 // Push the argument. 1806 // Push the argument.
1922 __ sw(a2, MemOperand(end_elements)); 1807 __ sw(a2, MemOperand(end_elements));
1923 // Fill the rest with holes. 1808 // Fill the rest with holes.
1924 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); 1809 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
1925 for (int i = 1; i < kAllocationDelta; i++) { 1810 for (int i = 1; i < kAllocationDelta; i++) {
1926 __ sw(a3, MemOperand(end_elements, i * kPointerSize)); 1811 __ sw(a3, MemOperand(end_elements, i * kPointerSize));
1927 } 1812 }
1928 1813
1929 // Update elements' and array's sizes. 1814 // Update elements' and array's sizes.
1930 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1815 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1931 __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta))); 1816 __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta)));
1932 __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1817 __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
1933 1818
1934 // Elements are in new space, so write barrier is not required. 1819 // Elements are in new space, so write barrier is not required.
1820 __ mov(v0, scratch);
1935 __ DropAndRet(argc + 1); 1821 __ DropAndRet(argc + 1);
1936 } 1822 }
1937 __ bind(&call_builtin); 1823 __ bind(&call_builtin);
1938 __ TailCallExternalReference( 1824 __ TailCallExternalReference(
1939 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); 1825 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1);
1940 } 1826 }
1941 1827
1942 // Handle call cache miss. 1828 HandlerFrontendFooter(&miss);
1943 __ bind(&miss);
1944 GenerateMissBranch();
1945 1829
1946 // Return the generated code. 1830 // Return the generated code.
1947 return GetCode(type, name); 1831 return GetCode(type, name);
1948 } 1832 }
1949 1833
1950 1834
1951 Handle<Code> CallStubCompiler::CompileArrayPopCall( 1835 Handle<Code> CallStubCompiler::CompileArrayPopCall(
1952 Handle<Object> object, 1836 Handle<Object> object,
1953 Handle<JSObject> holder, 1837 Handle<JSObject> holder,
1954 Handle<Cell> cell, 1838 Handle<Cell> cell,
1955 Handle<JSFunction> function, 1839 Handle<JSFunction> function,
1956 Handle<String> name, 1840 Handle<String> name,
1957 Code::StubType type) { 1841 Code::StubType type) {
1958 // ----------- S t a t e ------------- 1842 // If object is not an array or is observed or sealed, bail out to regular
1959 // -- a2 : name 1843 // call.
1960 // -- ra : return address
1961 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1962 // -- ...
1963 // -- sp[argc * 4] : receiver
1964 // -----------------------------------
1965
1966 // If object is not an array or is observed, bail out to regular call.
1967 if (!object->IsJSArray() || 1844 if (!object->IsJSArray() ||
1968 !cell.is_null() || 1845 !cell.is_null() ||
1969 Handle<JSArray>::cast(object)->map()->is_observed()) { 1846 Handle<JSArray>::cast(object)->map()->is_observed() ||
1847 !Handle<JSArray>::cast(object)->map()->is_extensible()) {
1970 return Handle<Code>::null(); 1848 return Handle<Code>::null();
1971 } 1849 }
1972 1850
1973 Label miss, return_undefined, call_builtin; 1851 Label miss, return_undefined, call_builtin;
1974 Register receiver = a1; 1852 Register receiver = a0;
1853 Register scratch = a1;
1975 Register elements = a3; 1854 Register elements = a3;
1976 GenerateNameCheck(name, &miss); 1855 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1977
1978 // Get the receiver from the stack.
1979 const int argc = arguments().immediate();
1980 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
1981 // Check that the receiver isn't a smi.
1982 __ JumpIfSmi(receiver, &miss);
1983
1984 // Check that the maps haven't changed.
1985 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, elements,
1986 t0, v0, name, &miss);
1987 1856
1988 // Get the elements array of the object. 1857 // Get the elements array of the object.
1989 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 1858 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
1990 1859
1991 // Check that the elements are in fast mode and writable. 1860 // Check that the elements are in fast mode and writable.
1992 __ CheckMap(elements, 1861 __ CheckMap(elements,
1993 v0, 1862 scratch,
1994 Heap::kFixedArrayMapRootIndex, 1863 Heap::kFixedArrayMapRootIndex,
1995 &call_builtin, 1864 &call_builtin,
1996 DONT_DO_SMI_CHECK); 1865 DONT_DO_SMI_CHECK);
1997 1866
1998 // Get the array's length into t0 and calculate new length. 1867 // Get the array's length into t0 and calculate new length.
1999 __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1868 __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
2000 __ Subu(t0, t0, Operand(Smi::FromInt(1))); 1869 __ Subu(t0, t0, Operand(Smi::FromInt(1)));
2001 __ Branch(&return_undefined, lt, t0, Operand(zero_reg)); 1870 __ Branch(&return_undefined, lt, t0, Operand(zero_reg));
2002 1871
2003 // Get the last element. 1872 // Get the last element.
2004 __ LoadRoot(t2, Heap::kTheHoleValueRootIndex); 1873 __ LoadRoot(t2, Heap::kTheHoleValueRootIndex);
2005 STATIC_ASSERT(kSmiTagSize == 1); 1874 STATIC_ASSERT(kSmiTagSize == 1);
2006 STATIC_ASSERT(kSmiTag == 0); 1875 STATIC_ASSERT(kSmiTag == 0);
2007 // We can't address the last element in one operation. Compute the more 1876 // We can't address the last element in one operation. Compute the more
2008 // expensive shift first, and use an offset later on. 1877 // expensive shift first, and use an offset later on.
2009 __ sll(t1, t0, kPointerSizeLog2 - kSmiTagSize); 1878 __ sll(t1, t0, kPointerSizeLog2 - kSmiTagSize);
2010 __ Addu(elements, elements, t1); 1879 __ Addu(elements, elements, t1);
2011 __ lw(v0, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1880 __ lw(scratch, FieldMemOperand(elements, FixedArray::kHeaderSize));
2012 __ Branch(&call_builtin, eq, v0, Operand(t2)); 1881 __ Branch(&call_builtin, eq, scratch, Operand(t2));
2013 1882
2014 // Set the array's length. 1883 // Set the array's length.
2015 __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1884 __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
2016 1885
2017 // Fill with the hole. 1886 // Fill with the hole.
2018 __ sw(t2, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1887 __ sw(t2, FieldMemOperand(elements, FixedArray::kHeaderSize));
1888 const int argc = arguments().immediate();
1889 __ mov(v0, scratch);
2019 __ DropAndRet(argc + 1); 1890 __ DropAndRet(argc + 1);
2020 1891
2021 __ bind(&return_undefined); 1892 __ bind(&return_undefined);
2022 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 1893 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
2023 __ DropAndRet(argc + 1); 1894 __ DropAndRet(argc + 1);
2024 1895
2025 __ bind(&call_builtin); 1896 __ bind(&call_builtin);
2026 __ TailCallExternalReference( 1897 __ TailCallExternalReference(
2027 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); 1898 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1);
2028 1899
2029 // Handle call cache miss. 1900 HandlerFrontendFooter(&miss);
2030 __ bind(&miss);
2031 GenerateMissBranch();
2032 1901
2033 // Return the generated code. 1902 // Return the generated code.
2034 return GetCode(type, name); 1903 return GetCode(type, name);
2035 } 1904 }
2036 1905
2037 1906
2038 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( 1907 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
2039 Handle<Object> object, 1908 Handle<Object> object,
2040 Handle<JSObject> holder, 1909 Handle<JSObject> holder,
2041 Handle<Cell> cell, 1910 Handle<Cell> cell,
2042 Handle<JSFunction> function, 1911 Handle<JSFunction> function,
2043 Handle<String> name, 1912 Handle<String> name,
2044 Code::StubType type) { 1913 Code::StubType type) {
2045 // ----------- S t a t e -------------
2046 // -- a2 : function name
2047 // -- ra : return address
2048 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2049 // -- ...
2050 // -- sp[argc * 4] : receiver
2051 // -----------------------------------
2052
2053 // If object is not a string, bail out to regular call. 1914 // If object is not a string, bail out to regular call.
2054 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 1915 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2055 1916
2056 const int argc = arguments().immediate();
2057 Label miss; 1917 Label miss;
2058 Label name_miss; 1918 Label name_miss;
2059 Label index_out_of_range; 1919 Label index_out_of_range;
2060 1920
2061 Label* index_out_of_range_label = &index_out_of_range; 1921 Label* index_out_of_range_label = &index_out_of_range;
2062 1922
2063 if (kind_ == Code::CALL_IC && 1923 if (kind_ == Code::CALL_IC &&
2064 (CallICBase::StringStubState::decode(extra_state_) == 1924 (CallICBase::StringStubState::decode(extra_state()) ==
2065 DEFAULT_STRING_STUB)) { 1925 DEFAULT_STRING_STUB)) {
2066 index_out_of_range_label = &miss; 1926 index_out_of_range_label = &miss;
2067 } 1927 }
2068 1928
2069 GenerateNameCheck(name, &name_miss); 1929 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2070 1930
2071 // Check that the maps starting from the prototype haven't changed. 1931 Register receiver = a0;
2072 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2073 Context::STRING_FUNCTION_INDEX,
2074 v0,
2075 &miss);
2076 ASSERT(!object.is_identical_to(holder));
2077 CheckPrototypes(
2078 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2079 v0, holder, a1, a3, t0, name, &miss);
2080
2081 Register receiver = a1;
2082 Register index = t1; 1932 Register index = t1;
2083 Register result = v0; 1933 Register result = a1;
1934 const int argc = arguments().immediate();
2084 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); 1935 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
2085 if (argc > 0) { 1936 if (argc > 0) {
2086 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); 1937 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize));
2087 } else { 1938 } else {
2088 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 1939 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2089 } 1940 }
2090 1941
2091 StringCharCodeAtGenerator generator(receiver, 1942 StringCharCodeAtGenerator generator(receiver,
2092 index, 1943 index,
2093 result, 1944 result,
2094 &miss, // When not a string. 1945 &miss, // When not a string.
2095 &miss, // When not a number. 1946 &miss, // When not a number.
2096 index_out_of_range_label, 1947 index_out_of_range_label,
2097 STRING_INDEX_IS_NUMBER); 1948 STRING_INDEX_IS_NUMBER);
2098 generator.GenerateFast(masm()); 1949 generator.GenerateFast(masm());
1950 __ mov(v0, result);
2099 __ DropAndRet(argc + 1); 1951 __ DropAndRet(argc + 1);
2100 1952
2101 StubRuntimeCallHelper call_helper; 1953 StubRuntimeCallHelper call_helper;
2102 generator.GenerateSlow(masm(), call_helper); 1954 generator.GenerateSlow(masm(), call_helper);
2103 1955
2104 if (index_out_of_range.is_linked()) { 1956 if (index_out_of_range.is_linked()) {
2105 __ bind(&index_out_of_range); 1957 __ bind(&index_out_of_range);
2106 __ LoadRoot(v0, Heap::kNanValueRootIndex); 1958 __ LoadRoot(v0, Heap::kNanValueRootIndex);
2107 __ DropAndRet(argc + 1); 1959 __ DropAndRet(argc + 1);
2108 } 1960 }
2109 1961
2110 __ bind(&miss); 1962 __ bind(&miss);
2111 // Restore function name in a2. 1963 // Restore function name in a2.
2112 __ li(a2, name); 1964 __ li(a2, name);
2113 __ bind(&name_miss); 1965 HandlerFrontendFooter(&name_miss);
2114 GenerateMissBranch();
2115 1966
2116 // Return the generated code. 1967 // Return the generated code.
2117 return GetCode(type, name); 1968 return GetCode(type, name);
2118 } 1969 }
2119 1970
2120 1971
2121 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 1972 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2122 Handle<Object> object, 1973 Handle<Object> object,
2123 Handle<JSObject> holder, 1974 Handle<JSObject> holder,
2124 Handle<Cell> cell, 1975 Handle<Cell> cell,
2125 Handle<JSFunction> function, 1976 Handle<JSFunction> function,
2126 Handle<String> name, 1977 Handle<String> name,
2127 Code::StubType type) { 1978 Code::StubType type) {
2128 // ----------- S t a t e -------------
2129 // -- a2 : function name
2130 // -- ra : return address
2131 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2132 // -- ...
2133 // -- sp[argc * 4] : receiver
2134 // -----------------------------------
2135
2136 // If object is not a string, bail out to regular call. 1979 // If object is not a string, bail out to regular call.
2137 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 1980 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2138 1981
2139 const int argc = arguments().immediate(); 1982 const int argc = arguments().immediate();
2140 Label miss; 1983 Label miss;
2141 Label name_miss; 1984 Label name_miss;
2142 Label index_out_of_range; 1985 Label index_out_of_range;
2143 Label* index_out_of_range_label = &index_out_of_range; 1986 Label* index_out_of_range_label = &index_out_of_range;
2144 if (kind_ == Code::CALL_IC && 1987 if (kind_ == Code::CALL_IC &&
2145 (CallICBase::StringStubState::decode(extra_state_) == 1988 (CallICBase::StringStubState::decode(extra_state()) ==
2146 DEFAULT_STRING_STUB)) { 1989 DEFAULT_STRING_STUB)) {
2147 index_out_of_range_label = &miss; 1990 index_out_of_range_label = &miss;
2148 } 1991 }
2149 GenerateNameCheck(name, &name_miss);
2150 1992
2151 // Check that the maps starting from the prototype haven't changed. 1993 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2152 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2153 Context::STRING_FUNCTION_INDEX,
2154 v0,
2155 &miss);
2156 ASSERT(!object.is_identical_to(holder));
2157 CheckPrototypes(
2158 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2159 v0, holder, a1, a3, t0, name, &miss);
2160 1994
2161 Register receiver = v0; 1995 Register receiver = a0;
2162 Register index = t1; 1996 Register index = t1;
2163 Register scratch = a3; 1997 Register scratch = a3;
2164 Register result = v0; 1998 Register result = a1;
2165 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
2166 if (argc > 0) { 1999 if (argc > 0) {
2167 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); 2000 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize));
2168 } else { 2001 } else {
2169 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2002 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2170 } 2003 }
2171 2004
2172 StringCharAtGenerator generator(receiver, 2005 StringCharAtGenerator generator(receiver,
2173 index, 2006 index,
2174 scratch, 2007 scratch,
2175 result, 2008 result,
2176 &miss, // When not a string. 2009 &miss, // When not a string.
2177 &miss, // When not a number. 2010 &miss, // When not a number.
2178 index_out_of_range_label, 2011 index_out_of_range_label,
2179 STRING_INDEX_IS_NUMBER); 2012 STRING_INDEX_IS_NUMBER);
2180 generator.GenerateFast(masm()); 2013 generator.GenerateFast(masm());
2014 __ mov(v0, result);
2181 __ DropAndRet(argc + 1); 2015 __ DropAndRet(argc + 1);
2182 2016
2183 StubRuntimeCallHelper call_helper; 2017 StubRuntimeCallHelper call_helper;
2184 generator.GenerateSlow(masm(), call_helper); 2018 generator.GenerateSlow(masm(), call_helper);
2185 2019
2186 if (index_out_of_range.is_linked()) { 2020 if (index_out_of_range.is_linked()) {
2187 __ bind(&index_out_of_range); 2021 __ bind(&index_out_of_range);
2188 __ LoadRoot(v0, Heap::kempty_stringRootIndex); 2022 __ LoadRoot(v0, Heap::kempty_stringRootIndex);
2189 __ DropAndRet(argc + 1); 2023 __ DropAndRet(argc + 1);
2190 } 2024 }
2191 2025
2192 __ bind(&miss); 2026 __ bind(&miss);
2193 // Restore function name in a2. 2027 // Restore function name in a2.
2194 __ li(a2, name); 2028 __ li(a2, name);
2195 __ bind(&name_miss); 2029 HandlerFrontendFooter(&name_miss);
2196 GenerateMissBranch();
2197 2030
2198 // Return the generated code. 2031 // Return the generated code.
2199 return GetCode(type, name); 2032 return GetCode(type, name);
2200 } 2033 }
2201 2034
2202 2035
2203 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2036 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2204 Handle<Object> object, 2037 Handle<Object> object,
2205 Handle<JSObject> holder, 2038 Handle<JSObject> holder,
2206 Handle<Cell> cell, 2039 Handle<Cell> cell,
2207 Handle<JSFunction> function, 2040 Handle<JSFunction> function,
2208 Handle<String> name, 2041 Handle<String> name,
2209 Code::StubType type) { 2042 Code::StubType type) {
2210 // ----------- S t a t e -------------
2211 // -- a2 : function name
2212 // -- ra : return address
2213 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2214 // -- ...
2215 // -- sp[argc * 4] : receiver
2216 // -----------------------------------
2217
2218 const int argc = arguments().immediate(); 2043 const int argc = arguments().immediate();
2219 2044
2220 // If the object is not a JSObject or we got an unexpected number of 2045 // If the object is not a JSObject or we got an unexpected number of
2221 // arguments, bail out to the regular call. 2046 // arguments, bail out to the regular call.
2222 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2047 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2223 2048
2224 Label miss; 2049 Label miss;
2225 GenerateNameCheck(name, &miss); 2050 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2226 2051 if (!cell.is_null()) {
2227 if (cell.is_null()) {
2228 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2229
2230 STATIC_ASSERT(kSmiTag == 0);
2231 __ JumpIfSmi(a1, &miss);
2232
2233 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, v0, a3, t0,
2234 name, &miss);
2235 } else {
2236 ASSERT(cell->value() == *function); 2052 ASSERT(cell->value() == *function);
2237 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2238 &miss);
2239 GenerateLoadFunctionFromCell(cell, function, &miss); 2053 GenerateLoadFunctionFromCell(cell, function, &miss);
2240 } 2054 }
2241 2055
2242 // Load the char code argument. 2056 // Load the char code argument.
2243 Register code = a1; 2057 Register code = a1;
2244 __ lw(code, MemOperand(sp, 0 * kPointerSize)); 2058 __ lw(code, MemOperand(sp, 0 * kPointerSize));
2245 2059
2246 // Check the code is a smi. 2060 // Check the code is a smi.
2247 Label slow; 2061 Label slow;
2248 STATIC_ASSERT(kSmiTag == 0); 2062 STATIC_ASSERT(kSmiTag == 0);
2249 __ JumpIfNotSmi(code, &slow); 2063 __ JumpIfNotSmi(code, &slow);
2250 2064
2251 // Convert the smi code to uint16. 2065 // Convert the smi code to uint16.
2252 __ And(code, code, Operand(Smi::FromInt(0xffff))); 2066 __ And(code, code, Operand(Smi::FromInt(0xffff)));
2253 2067
2254 StringCharFromCodeGenerator generator(code, v0); 2068 StringCharFromCodeGenerator generator(code, v0);
2255 generator.GenerateFast(masm()); 2069 generator.GenerateFast(masm());
2256 __ DropAndRet(argc + 1); 2070 __ DropAndRet(argc + 1);
2257 2071
2258 StubRuntimeCallHelper call_helper; 2072 StubRuntimeCallHelper call_helper;
2259 generator.GenerateSlow(masm(), call_helper); 2073 generator.GenerateSlow(masm(), call_helper);
2260 2074
2261 // Tail call the full function. We do not have to patch the receiver
2262 // because the function makes no use of it.
2263 __ bind(&slow); 2075 __ bind(&slow);
2264 ParameterCount expected(function); 2076 // We do not have to patch the receiver because the function makes no use of
2265 __ InvokeFunction(function, expected, arguments(), 2077 // it.
2266 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2078 GenerateJumpFunctionIgnoreReceiver(function);
2267 2079
2268 __ bind(&miss); 2080 HandlerFrontendFooter(&miss);
2269 // a2: function name.
2270 GenerateMissBranch();
2271 2081
2272 // Return the generated code. 2082 // Return the generated code.
2273 return GetCode(type, name); 2083 return GetCode(type, name);
2274 } 2084 }
2275 2085
2276 2086
2277 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2087 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2278 Handle<Object> object, 2088 Handle<Object> object,
2279 Handle<JSObject> holder, 2089 Handle<JSObject> holder,
2280 Handle<Cell> cell, 2090 Handle<Cell> cell,
2281 Handle<JSFunction> function, 2091 Handle<JSFunction> function,
2282 Handle<String> name, 2092 Handle<String> name,
2283 Code::StubType type) { 2093 Code::StubType type) {
2284 // ----------- S t a t e -------------
2285 // -- a2 : function name
2286 // -- ra : return address
2287 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2288 // -- ...
2289 // -- sp[argc * 4] : receiver
2290 // -----------------------------------
2291
2292
2293 const int argc = arguments().immediate(); 2094 const int argc = arguments().immediate();
2294 // If the object is not a JSObject or we got an unexpected number of 2095 // If the object is not a JSObject or we got an unexpected number of
2295 // arguments, bail out to the regular call. 2096 // arguments, bail out to the regular call.
2296 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2097 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2297 2098
2298 Label miss, slow; 2099 Label miss, slow;
2299 GenerateNameCheck(name, &miss); 2100 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2300 2101 if (!cell.is_null()) {
2301 if (cell.is_null()) {
2302 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2303 STATIC_ASSERT(kSmiTag == 0);
2304 __ JumpIfSmi(a1, &miss);
2305 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0,
2306 name, &miss);
2307 } else {
2308 ASSERT(cell->value() == *function); 2102 ASSERT(cell->value() == *function);
2309 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2310 &miss);
2311 GenerateLoadFunctionFromCell(cell, function, &miss); 2103 GenerateLoadFunctionFromCell(cell, function, &miss);
2312 } 2104 }
2313 2105
2314 // Load the (only) argument into v0. 2106 // Load the (only) argument into v0.
2315 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); 2107 __ lw(v0, MemOperand(sp, 0 * kPointerSize));
2316 2108
2317 // If the argument is a smi, just return. 2109 // If the argument is a smi, just return.
2318 STATIC_ASSERT(kSmiTag == 0); 2110 STATIC_ASSERT(kSmiTag == 0);
2319 __ SmiTst(v0, t0); 2111 __ SmiTst(v0, t0);
2320 __ DropAndRet(argc + 1, eq, t0, Operand(zero_reg)); 2112 __ DropAndRet(argc + 1, eq, t0, Operand(zero_reg));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2382 // Restore FCSR and return. 2174 // Restore FCSR and return.
2383 __ ctc1(a3, FCSR); 2175 __ ctc1(a3, FCSR);
2384 2176
2385 __ DropAndRet(argc + 1); 2177 __ DropAndRet(argc + 1);
2386 2178
2387 __ bind(&wont_fit_smi); 2179 __ bind(&wont_fit_smi);
2388 // Restore FCSR and fall to slow case. 2180 // Restore FCSR and fall to slow case.
2389 __ ctc1(a3, FCSR); 2181 __ ctc1(a3, FCSR);
2390 2182
2391 __ bind(&slow); 2183 __ bind(&slow);
2392 // Tail call the full function. We do not have to patch the receiver 2184 // We do not have to patch the receiver because the function makes no use of
2393 // because the function makes no use of it. 2185 // it.
2394 ParameterCount expected(function); 2186 GenerateJumpFunctionIgnoreReceiver(function);
2395 __ InvokeFunction(function, expected, arguments(),
2396 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2397 2187
2398 __ bind(&miss); 2188 HandlerFrontendFooter(&miss);
2399 // a2: function name.
2400 GenerateMissBranch();
2401 2189
2402 // Return the generated code. 2190 // Return the generated code.
2403 return GetCode(type, name); 2191 return GetCode(type, name);
2404 } 2192 }
2405 2193
2406 2194
2407 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2195 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2408 Handle<Object> object, 2196 Handle<Object> object,
2409 Handle<JSObject> holder, 2197 Handle<JSObject> holder,
2410 Handle<Cell> cell, 2198 Handle<Cell> cell,
2411 Handle<JSFunction> function, 2199 Handle<JSFunction> function,
2412 Handle<String> name, 2200 Handle<String> name,
2413 Code::StubType type) { 2201 Code::StubType type) {
2414 // ----------- S t a t e -------------
2415 // -- a2 : function name
2416 // -- ra : return address
2417 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2418 // -- ...
2419 // -- sp[argc * 4] : receiver
2420 // -----------------------------------
2421
2422 const int argc = arguments().immediate(); 2202 const int argc = arguments().immediate();
2423 // If the object is not a JSObject or we got an unexpected number of 2203 // If the object is not a JSObject or we got an unexpected number of
2424 // arguments, bail out to the regular call. 2204 // arguments, bail out to the regular call.
2425 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2205 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2426 2206
2427 Label miss; 2207 Label miss;
2428 2208
2429 GenerateNameCheck(name, &miss); 2209 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2430 if (cell.is_null()) { 2210 if (!cell.is_null()) {
2431 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2432 STATIC_ASSERT(kSmiTag == 0);
2433 __ JumpIfSmi(a1, &miss);
2434 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, v0, a3, t0,
2435 name, &miss);
2436 } else {
2437 ASSERT(cell->value() == *function); 2211 ASSERT(cell->value() == *function);
2438 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2439 &miss);
2440 GenerateLoadFunctionFromCell(cell, function, &miss); 2212 GenerateLoadFunctionFromCell(cell, function, &miss);
2441 } 2213 }
2442 2214
2443 // Load the (only) argument into v0. 2215 // Load the (only) argument into v0.
2444 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); 2216 __ lw(v0, MemOperand(sp, 0 * kPointerSize));
2445 2217
2446 // Check if the argument is a smi. 2218 // Check if the argument is a smi.
2447 Label not_smi; 2219 Label not_smi;
2448 STATIC_ASSERT(kSmiTag == 0); 2220 STATIC_ASSERT(kSmiTag == 0);
2449 __ JumpIfNotSmi(v0, &not_smi); 2221 __ JumpIfNotSmi(v0, &not_smi);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2481 // number. 2253 // number.
2482 __ bind(&negative_sign); 2254 __ bind(&negative_sign);
2483 __ Xor(a1, a1, Operand(HeapNumber::kSignMask)); 2255 __ Xor(a1, a1, Operand(HeapNumber::kSignMask));
2484 __ lw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); 2256 __ lw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
2485 __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex); 2257 __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex);
2486 __ AllocateHeapNumber(v0, t0, t1, t2, &slow); 2258 __ AllocateHeapNumber(v0, t0, t1, t2, &slow);
2487 __ sw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset)); 2259 __ sw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset));
2488 __ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); 2260 __ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
2489 __ DropAndRet(argc + 1); 2261 __ DropAndRet(argc + 1);
2490 2262
2491 // Tail call the full function. We do not have to patch the receiver
2492 // because the function makes no use of it.
2493 __ bind(&slow); 2263 __ bind(&slow);
2494 ParameterCount expected(function); 2264 // We do not have to patch the receiver because the function makes no use of
2495 __ InvokeFunction(function, expected, arguments(), 2265 // it.
2496 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2266 GenerateJumpFunctionIgnoreReceiver(function);
2497 2267
2498 __ bind(&miss); 2268 HandlerFrontendFooter(&miss);
2499 // a2: function name.
2500 GenerateMissBranch();
2501 2269
2502 // Return the generated code. 2270 // Return the generated code.
2503 return GetCode(type, name); 2271 return GetCode(type, name);
2504 } 2272 }
2505 2273
2506 2274
2507 Handle<Code> CallStubCompiler::CompileFastApiCall( 2275 Handle<Code> CallStubCompiler::CompileFastApiCall(
2508 const CallOptimization& optimization, 2276 const CallOptimization& optimization,
2509 Handle<Object> object, 2277 Handle<Object> object,
2510 Handle<JSObject> holder, 2278 Handle<JSObject> holder,
(...skipping 23 matching lines...) Expand all
2534 2302
2535 // Check that the receiver isn't a smi. 2303 // Check that the receiver isn't a smi.
2536 __ JumpIfSmi(a1, &miss_before_stack_reserved); 2304 __ JumpIfSmi(a1, &miss_before_stack_reserved);
2537 2305
2538 __ IncrementCounter(counters->call_const(), 1, a0, a3); 2306 __ IncrementCounter(counters->call_const(), 1, a0, a3);
2539 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); 2307 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3);
2540 2308
2541 ReserveSpaceForFastApiCall(masm(), a0); 2309 ReserveSpaceForFastApiCall(masm(), a0);
2542 2310
2543 // Check that the maps haven't changed and find a Holder as a side effect. 2311 // Check that the maps haven't changed and find a Holder as a side effect.
2544 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, name, 2312 CheckPrototypes(
2545 depth, &miss); 2313 IC::CurrentTypeOf(object, isolate()),
2314 a1, holder, a0, a3, t0, name, depth, &miss);
2546 2315
2547 GenerateFastApiDirectCall(masm(), optimization, argc, false); 2316 GenerateFastApiDirectCall(masm(), optimization, argc, false);
2548 2317
2549 __ bind(&miss); 2318 __ bind(&miss);
2550 FreeSpaceForFastApiCall(masm()); 2319 FreeSpaceForFastApiCall(masm());
2551 2320
2552 __ bind(&miss_before_stack_reserved); 2321 HandlerFrontendFooter(&miss_before_stack_reserved);
2553 GenerateMissBranch();
2554 2322
2555 // Return the generated code. 2323 // Return the generated code.
2556 return GetCode(function); 2324 return GetCode(function);
2557 } 2325 }
2558 2326
2559 2327
2560 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2328 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2561 Label success; 2329 Label success;
2562 // Check that the object is a boolean. 2330 // Check that the object is a boolean.
2563 __ LoadRoot(at, Heap::kTrueValueRootIndex); 2331 __ LoadRoot(at, Heap::kTrueValueRootIndex);
2564 __ Branch(&success, eq, object, Operand(at)); 2332 __ Branch(&success, eq, object, Operand(at));
2565 __ LoadRoot(at, Heap::kFalseValueRootIndex); 2333 __ LoadRoot(at, Heap::kFalseValueRootIndex);
2566 __ Branch(miss, ne, object, Operand(at)); 2334 __ Branch(miss, ne, object, Operand(at));
2567 __ bind(&success); 2335 __ bind(&success);
2568 } 2336 }
2569 2337
2570 2338
2571 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2339 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2572 Handle<JSObject> holder, 2340 if (object->IsGlobalObject()) {
2573 Handle<Name> name, 2341 const int argc = arguments().immediate();
2574 CheckType check) { 2342 const int receiver_offset = argc * kPointerSize;
2343 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
2344 __ sw(a3, MemOperand(sp, receiver_offset));
2345 }
2346 }
2347
2348
2349 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2350 Handle<JSObject> holder,
2351 Handle<Name> name,
2352 CheckType check,
2353 Label* miss) {
2575 // ----------- S t a t e ------------- 2354 // ----------- S t a t e -------------
2576 // -- a2 : name 2355 // -- a2 : name
2577 // -- ra : return address 2356 // -- ra : return address
2578 // ----------------------------------- 2357 // -----------------------------------
2579 Label miss; 2358 GenerateNameCheck(name, miss);
2580 GenerateNameCheck(name, &miss); 2359
2360 Register reg = a0;
2581 2361
2582 // Get the receiver from the stack. 2362 // Get the receiver from the stack.
2583 const int argc = arguments().immediate(); 2363 const int argc = arguments().immediate();
2584 __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2364 const int receiver_offset = argc * kPointerSize;
2365 __ lw(a0, MemOperand(sp, receiver_offset));
2585 2366
2586 // Check that the receiver isn't a smi. 2367 // Check that the receiver isn't a smi.
2587 if (check != NUMBER_CHECK) { 2368 if (check != NUMBER_CHECK) {
2588 __ JumpIfSmi(a1, &miss); 2369 __ JumpIfSmi(a0, miss);
2589 } 2370 }
2590 2371
2591 // Make sure that it's okay not to patch the on stack receiver 2372 // Make sure that it's okay not to patch the on stack receiver
2592 // unless we're doing a receiver map check. 2373 // unless we're doing a receiver map check.
2593 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2374 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2594 switch (check) { 2375 switch (check) {
2595 case RECEIVER_MAP_CHECK: 2376 case RECEIVER_MAP_CHECK:
2596 __ IncrementCounter(isolate()->counters()->call_const(), 1, a0, a3); 2377 __ IncrementCounter(isolate()->counters()->call_const(), 1, a1, a3);
2597 2378
2598 // Check that the maps haven't changed. 2379 // Check that the maps haven't changed.
2599 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, 2380 reg = CheckPrototypes(
2600 name, &miss); 2381 IC::CurrentTypeOf(object, isolate()),
2601 2382 reg, holder, a1, a3, t0, name, miss);
2602 // Patch the receiver on the stack with the global proxy if
2603 // necessary.
2604 if (object->IsGlobalObject()) {
2605 __ lw(a3, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset));
2606 __ sw(a3, MemOperand(sp, argc * kPointerSize));
2607 }
2608 break; 2383 break;
2609 2384
2610 case STRING_CHECK: 2385 case STRING_CHECK: {
2611 // Check that the object is a string. 2386 // Check that the object is a string.
2612 __ GetObjectType(a1, a3, a3); 2387 __ GetObjectType(reg, a3, a3);
2613 __ Branch(&miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE)); 2388 __ Branch(miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE));
2614 // Check that the maps starting from the prototype haven't changed. 2389 // Check that the maps starting from the prototype haven't changed.
2615 GenerateDirectLoadGlobalFunctionPrototype( 2390 GenerateDirectLoadGlobalFunctionPrototype(
2616 masm(), Context::STRING_FUNCTION_INDEX, a0, &miss); 2391 masm(), Context::STRING_FUNCTION_INDEX, a1, miss);
2617 CheckPrototypes(
2618 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2619 a0, holder, a3, a1, t0, name, &miss);
2620 break; 2392 break;
2621 2393 }
2622 case SYMBOL_CHECK: 2394 case SYMBOL_CHECK: {
2623 // Check that the object is a symbol. 2395 // Check that the object is a symbol.
2624 __ GetObjectType(a1, a1, a3); 2396 __ GetObjectType(reg, a1, a3);
2625 __ Branch(&miss, ne, a3, Operand(SYMBOL_TYPE)); 2397 __ Branch(miss, ne, a3, Operand(SYMBOL_TYPE));
2626 // Check that the maps starting from the prototype haven't changed. 2398 // Check that the maps starting from the prototype haven't changed.
2627 GenerateDirectLoadGlobalFunctionPrototype( 2399 GenerateDirectLoadGlobalFunctionPrototype(
2628 masm(), Context::SYMBOL_FUNCTION_INDEX, a0, &miss); 2400 masm(), Context::SYMBOL_FUNCTION_INDEX, a1, miss);
2629 CheckPrototypes(
2630 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2631 a0, holder, a3, a1, t0, name, &miss);
2632 break; 2401 break;
2633 2402 }
2634 case NUMBER_CHECK: { 2403 case NUMBER_CHECK: {
2635 Label fast; 2404 Label fast;
2636 // Check that the object is a smi or a heap number. 2405 // Check that the object is a smi or a heap number.
2637 __ JumpIfSmi(a1, &fast); 2406 __ JumpIfSmi(reg, &fast);
2638 __ GetObjectType(a1, a0, a0); 2407 __ GetObjectType(reg, a3, a3);
2639 __ Branch(&miss, ne, a0, Operand(HEAP_NUMBER_TYPE)); 2408 __ Branch(miss, ne, a3, Operand(HEAP_NUMBER_TYPE));
2640 __ bind(&fast); 2409 __ bind(&fast);
2641 // Check that the maps starting from the prototype haven't changed. 2410 // Check that the maps starting from the prototype haven't changed.
2642 GenerateDirectLoadGlobalFunctionPrototype( 2411 GenerateDirectLoadGlobalFunctionPrototype(
2643 masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss); 2412 masm(), Context::NUMBER_FUNCTION_INDEX, a1, miss);
2644 CheckPrototypes(
2645 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2646 a0, holder, a3, a1, t0, name, &miss);
2647 break; 2413 break;
2648 } 2414 }
2649 case BOOLEAN_CHECK: { 2415 case BOOLEAN_CHECK: {
2650 GenerateBooleanCheck(a1, &miss); 2416 GenerateBooleanCheck(reg, miss);
2651 2417
2652 // Check that the maps starting from the prototype haven't changed. 2418 // Check that the maps starting from the prototype haven't changed.
2653 GenerateDirectLoadGlobalFunctionPrototype( 2419 GenerateDirectLoadGlobalFunctionPrototype(
2654 masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss); 2420 masm(), Context::BOOLEAN_FUNCTION_INDEX, a1, miss);
2655 CheckPrototypes(
2656 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2657 a0, holder, a3, a1, t0, name, &miss);
2658 break; 2421 break;
2659 } 2422 }
2660 } 2423 }
2661 2424
2662 Label success; 2425 if (check != RECEIVER_MAP_CHECK) {
2663 __ Branch(&success); 2426 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2427 reg = CheckPrototypes(
2428 IC::CurrentTypeOf(prototype, isolate()),
2429 a1, holder, a1, a3, t0, name, miss);
2430 }
2664 2431
2665 // Handle call cache miss. 2432 return reg;
2666 __ bind(&miss);
2667
2668 GenerateMissBranch();
2669
2670 __ bind(&success);
2671 } 2433 }
2672 2434
2673 2435
2674 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2436 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
2675 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2437 Register function,
2676 ? CALL_AS_FUNCTION 2438 Label* miss) {
2677 : CALL_AS_METHOD; 2439 ASSERT(function.is(a1));
2678 ParameterCount expected(function); 2440 // Check that the function really is a function.
2679 __ InvokeFunction(function, expected, arguments(), 2441 GenerateFunctionCheck(function, a3, miss);
2680 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2442 PatchGlobalProxy(object);
2681 } 2443 // Invoke the function.
2682 2444 __ InvokeFunction(a1, arguments(), JUMP_FUNCTION,
2683 2445 NullCallWrapper(), call_kind());
2684 Handle<Code> CallStubCompiler::CompileCallConstant(
2685 Handle<Object> object,
2686 Handle<JSObject> holder,
2687 Handle<Name> name,
2688 CheckType check,
2689 Handle<JSFunction> function) {
2690 if (HasCustomCallGenerator(function)) {
2691 Handle<Code> code = CompileCustomCall(object, holder,
2692 Handle<Cell>::null(),
2693 function, Handle<String>::cast(name),
2694 Code::FAST);
2695 // A null handle means bail out to the regular compiler code below.
2696 if (!code.is_null()) return code;
2697 }
2698
2699 CompileHandlerFrontend(object, holder, name, check);
2700 CompileHandlerBackend(function);
2701
2702 // Return the generated code.
2703 return GetCode(function);
2704 } 2446 }
2705 2447
2706 2448
2707 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2449 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2708 Handle<JSObject> holder, 2450 Handle<JSObject> holder,
2709 Handle<Name> name) { 2451 Handle<Name> name) {
2710 // ----------- S t a t e -------------
2711 // -- a2 : name
2712 // -- ra : return address
2713 // -----------------------------------
2714
2715 Label miss; 2452 Label miss;
2716 2453
2717 GenerateNameCheck(name, &miss); 2454 GenerateNameCheck(name, &miss);
2718 2455
2719 // Get the number of arguments. 2456 // Get the number of arguments.
2720 const int argc = arguments().immediate(); 2457 const int argc = arguments().immediate();
2721 LookupResult lookup(isolate()); 2458 LookupResult lookup(isolate());
2722 LookupPostInterceptor(holder, name, &lookup); 2459 LookupPostInterceptor(holder, name, &lookup);
2723 2460
2724 // Get the receiver from the stack. 2461 // Get the receiver from the stack.
2725 __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2462 __ lw(a1, MemOperand(sp, argc * kPointerSize));
2726 2463
2727 CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_); 2464 CallInterceptorCompiler compiler(this, arguments(), a2);
2728 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0, 2465 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0,
2729 &miss); 2466 &miss);
2730 2467
2731 // Move returned value, the function to call, to a1. 2468 // Move returned value, the function to call, to a1.
2732 __ mov(a1, v0); 2469 __ mov(a1, v0);
2733 // Restore receiver. 2470 // Restore receiver.
2734 __ lw(a0, MemOperand(sp, argc * kPointerSize)); 2471 __ lw(a0, MemOperand(sp, argc * kPointerSize));
2735 2472
2736 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); 2473 GenerateJumpFunction(object, a1, &miss);
2737 2474
2738 // Handle call cache miss. 2475 HandlerFrontendFooter(&miss);
2739 __ bind(&miss);
2740 GenerateMissBranch();
2741 2476
2742 // Return the generated code. 2477 // Return the generated code.
2743 return GetCode(Code::FAST, name); 2478 return GetCode(Code::FAST, name);
2744 } 2479 }
2745 2480
2746 2481
2747 Handle<Code> CallStubCompiler::CompileCallGlobal( 2482 Handle<Code> CallStubCompiler::CompileCallGlobal(
2748 Handle<JSObject> object, 2483 Handle<JSObject> object,
2749 Handle<GlobalObject> holder, 2484 Handle<GlobalObject> holder,
2750 Handle<PropertyCell> cell, 2485 Handle<PropertyCell> cell,
2751 Handle<JSFunction> function, 2486 Handle<JSFunction> function,
2752 Handle<Name> name) { 2487 Handle<Name> name) {
2753 // ----------- S t a t e -------------
2754 // -- a2 : name
2755 // -- ra : return address
2756 // -----------------------------------
2757
2758 if (HasCustomCallGenerator(function)) { 2488 if (HasCustomCallGenerator(function)) {
2759 Handle<Code> code = CompileCustomCall( 2489 Handle<Code> code = CompileCustomCall(
2760 object, holder, cell, function, Handle<String>::cast(name), 2490 object, holder, cell, function, Handle<String>::cast(name),
2761 Code::NORMAL); 2491 Code::NORMAL);
2762 // A null handle means bail out to the regular compiler code below. 2492 // A null handle means bail out to the regular compiler code below.
2763 if (!code.is_null()) return code; 2493 if (!code.is_null()) return code;
2764 } 2494 }
2765 2495
2766 Label miss; 2496 Label miss;
2767 GenerateNameCheck(name, &miss); 2497 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2768 2498 // Potentially loads a closure that matches the shared function info of the
2769 // Get the number of arguments. 2499 // function, rather than function.
2770 const int argc = arguments().immediate();
2771 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2772 GenerateLoadFunctionFromCell(cell, function, &miss); 2500 GenerateLoadFunctionFromCell(cell, function, &miss);
2773
2774 // Patch the receiver on the stack with the global proxy if
2775 // necessary.
2776 if (object->IsGlobalObject()) {
2777 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
2778 __ sw(a3, MemOperand(sp, argc * kPointerSize));
2779 }
2780
2781 // Set up the context (function already in r1).
2782 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
2783
2784 // Jump to the cached code (tail call).
2785 Counters* counters = isolate()->counters(); 2501 Counters* counters = isolate()->counters();
2786 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); 2502 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0);
2787 ParameterCount expected(function->shared()->formal_parameter_count()); 2503 GenerateJumpFunction(object, a1, function);
2788 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2504 HandlerFrontendFooter(&miss);
2789 ? CALL_AS_FUNCTION
2790 : CALL_AS_METHOD;
2791 // We call indirectly through the code field in the function to
2792 // allow recompilation to take effect without changing any of the
2793 // call sites.
2794 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
2795 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION,
2796 NullCallWrapper(), call_kind);
2797
2798 // Handle call cache miss.
2799 __ bind(&miss);
2800 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3);
2801 GenerateMissBranch();
2802 2505
2803 // Return the generated code. 2506 // Return the generated code.
2804 return GetCode(Code::NORMAL, name); 2507 return GetCode(Code::NORMAL, name);
2805 } 2508 }
2806 2509
2807 2510
2808 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2511 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2809 Handle<JSObject> object, 2512 Handle<JSObject> object,
2810 Handle<JSObject> holder, 2513 Handle<JSObject> holder,
2811 Handle<Name> name, 2514 Handle<Name> name,
2812 Handle<ExecutableAccessorInfo> callback) { 2515 Handle<ExecutableAccessorInfo> callback) {
2813 HandlerFrontend(object, receiver(), holder, name); 2516 HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
2517 receiver(), holder, name);
2814 2518
2815 // Stub never generated for non-global objects that require access 2519 // Stub never generated for non-global objects that require access
2816 // checks. 2520 // checks.
2817 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 2521 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
2818 2522
2819 __ push(receiver()); // Receiver. 2523 __ push(receiver()); // Receiver.
2820 __ li(at, Operand(callback)); // Callback info. 2524 __ li(at, Operand(callback)); // Callback info.
2821 __ push(at); 2525 __ push(at);
2822 __ li(at, Operand(name)); 2526 __ li(at, Operand(name));
2823 __ Push(at, value()); 2527 __ Push(at, value());
2824 2528
2825 // Do tail-call to the runtime system. 2529 // Do tail-call to the runtime system.
2826 ExternalReference store_callback_property = 2530 ExternalReference store_callback_property =
2827 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2531 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2828 __ TailCallExternalReference(store_callback_property, 4, 1); 2532 __ TailCallExternalReference(store_callback_property, 4, 1);
2829 2533
2830 // Return the generated code. 2534 // Return the generated code.
2831 return GetCode(kind(), Code::FAST, name); 2535 return GetCode(kind(), Code::FAST, name);
2832 } 2536 }
2833 2537
2834 2538
2835 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2539 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2836 Handle<JSObject> object, 2540 Handle<JSObject> object,
2837 Handle<JSObject> holder, 2541 Handle<JSObject> holder,
2838 Handle<Name> name, 2542 Handle<Name> name,
2839 const CallOptimization& call_optimization) { 2543 const CallOptimization& call_optimization) {
2840 HandlerFrontend(object, receiver(), holder, name); 2544 HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
2545 receiver(), holder, name);
2841 2546
2842 Register values[] = { value() }; 2547 Register values[] = { value() };
2843 GenerateFastApiCall( 2548 GenerateFastApiCall(
2844 masm(), call_optimization, receiver(), scratch3(), 1, values); 2549 masm(), call_optimization, receiver(), scratch3(), 1, values);
2845 2550
2846 // Return the generated code. 2551 // Return the generated code.
2847 return GetCode(kind(), Code::FAST, name); 2552 return GetCode(kind(), Code::FAST, name);
2848 } 2553 }
2849 2554
2850 2555
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2908 if (object->IsJSGlobalProxy()) { 2613 if (object->IsJSGlobalProxy()) {
2909 __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss); 2614 __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss);
2910 } 2615 }
2911 2616
2912 // Stub is never generated for non-global objects that require access 2617 // Stub is never generated for non-global objects that require access
2913 // checks. 2618 // checks.
2914 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 2619 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
2915 2620
2916 __ Push(receiver(), this->name(), value()); 2621 __ Push(receiver(), this->name(), value());
2917 2622
2918 __ li(scratch1(), Operand(Smi::FromInt(strict_mode())));
2919 __ push(scratch1()); // strict mode
2920
2921 // Do tail-call to the runtime system. 2623 // Do tail-call to the runtime system.
2922 ExternalReference store_ic_property = 2624 ExternalReference store_ic_property =
2923 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 2625 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
2924 __ TailCallExternalReference(store_ic_property, 4, 1); 2626 __ TailCallExternalReference(store_ic_property, 3, 1);
2925 2627
2926 // Handle store cache miss. 2628 // Handle store cache miss.
2927 __ bind(&miss); 2629 __ bind(&miss);
2928 TailCallBuiltin(masm(), MissBuiltin(kind())); 2630 TailCallBuiltin(masm(), MissBuiltin(kind()));
2929 2631
2930 // Return the generated code. 2632 // Return the generated code.
2931 return GetCode(kind(), Code::FAST, name); 2633 return GetCode(kind(), Code::FAST, name);
2932 } 2634 }
2933 2635
2934 2636
2935 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 2637 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<Type> type,
2936 Handle<Object> object, 2638 Handle<JSObject> last,
2937 Handle<JSObject> last, 2639 Handle<Name> name) {
2938 Handle<Name> name, 2640 NonexistentHandlerFrontend(type, last, name);
2939 Handle<JSGlobalObject> global) {
2940 NonexistentHandlerFrontend(object, last, name, global);
2941 2641
2942 // Return undefined if maps of the full prototype chain is still the same. 2642 // Return undefined if maps of the full prototype chain is still the same.
2943 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 2643 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
2944 __ Ret(); 2644 __ Ret();
2945 2645
2946 // Return the generated code. 2646 // Return the generated code.
2947 return GetCode(kind(), Code::FAST, name); 2647 return GetCode(kind(), Code::FAST, name);
2948 } 2648 }
2949 2649
2950 2650
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
3023 } 2723 }
3024 __ Ret(); 2724 __ Ret();
3025 } 2725 }
3026 2726
3027 2727
3028 #undef __ 2728 #undef __
3029 #define __ ACCESS_MASM(masm()) 2729 #define __ ACCESS_MASM(masm())
3030 2730
3031 2731
3032 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 2732 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
3033 Handle<Object> object, 2733 Handle<Type> type,
3034 Handle<GlobalObject> global, 2734 Handle<GlobalObject> global,
3035 Handle<PropertyCell> cell, 2735 Handle<PropertyCell> cell,
3036 Handle<Name> name, 2736 Handle<Name> name,
3037 bool is_dont_delete) { 2737 bool is_dont_delete) {
3038 Label miss; 2738 Label miss;
3039 2739
3040 HandlerFrontendHeader(object, receiver(), global, name, &miss); 2740 HandlerFrontendHeader(type, receiver(), global, name, &miss);
3041 2741
3042 // Get the value from the cell. 2742 // Get the value from the cell.
3043 __ li(a3, Operand(cell)); 2743 __ li(a3, Operand(cell));
3044 __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset)); 2744 __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset));
3045 2745
3046 // Check for deleted property if property can actually be deleted. 2746 // Check for deleted property if property can actually be deleted.
3047 if (!is_dont_delete) { 2747 if (!is_dont_delete) {
3048 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2748 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
3049 __ Branch(&miss, eq, t0, Operand(at)); 2749 __ Branch(&miss, eq, t0, Operand(at));
3050 } 2750 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
3183 // ----------------------------------- 2883 // -----------------------------------
3184 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2884 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3185 } 2885 }
3186 2886
3187 2887
3188 #undef __ 2888 #undef __
3189 2889
3190 } } // namespace v8::internal 2890 } } // namespace v8::internal
3191 2891
3192 #endif // V8_TARGET_ARCH_MIPS 2892 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/simulator-mips.cc ('k') | src/object-observe.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698