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

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

Powered by Google App Engine
This is Rietveld 408576698