OLD | NEW |
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 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 | 1067 |
1068 | 1068 |
1069 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1069 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
1070 Register object_reg, | 1070 Register object_reg, |
1071 Handle<JSObject> holder, | 1071 Handle<JSObject> holder, |
1072 Register holder_reg, | 1072 Register holder_reg, |
1073 Register scratch1, | 1073 Register scratch1, |
1074 Register scratch2, | 1074 Register scratch2, |
1075 Handle<String> name, | 1075 Handle<String> name, |
1076 int save_at_depth, | 1076 int save_at_depth, |
1077 Label* miss) { | 1077 Label* miss, |
| 1078 PrototypeCheckType check) { |
| 1079 Handle<JSObject> first = object; |
1078 // Make sure there's no overlap between holder and object registers. | 1080 // Make sure there's no overlap between holder and object registers. |
1079 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 1081 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
1080 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 1082 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
1081 && !scratch2.is(scratch1)); | 1083 && !scratch2.is(scratch1)); |
1082 | 1084 |
1083 // Keep track of the current object in register reg. | 1085 // Keep track of the current object in register reg. |
1084 Register reg = object_reg; | 1086 Register reg = object_reg; |
1085 int depth = 0; | 1087 int depth = 0; |
1086 | 1088 |
1087 if (save_at_depth == depth) { | 1089 if (save_at_depth == depth) { |
(...skipping 21 matching lines...) Expand all Loading... |
1109 StringDictionary::kNotFound); | 1111 StringDictionary::kNotFound); |
1110 | 1112 |
1111 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 1113 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
1112 scratch1, scratch2); | 1114 scratch1, scratch2); |
1113 | 1115 |
1114 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1116 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1115 reg = holder_reg; // From now on the object will be in holder_reg. | 1117 reg = holder_reg; // From now on the object will be in holder_reg. |
1116 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1118 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
1117 } else { | 1119 } else { |
1118 Handle<Map> current_map(current->map()); | 1120 Handle<Map> current_map(current->map()); |
1119 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK, | 1121 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { |
1120 ALLOW_ELEMENT_TRANSITION_MAPS); | 1122 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK, |
| 1123 ALLOW_ELEMENT_TRANSITION_MAPS); |
| 1124 } |
1121 | 1125 |
1122 // Check access rights to the global object. This has to happen after | 1126 // Check access rights to the global object. This has to happen after |
1123 // the map check so that we know that the object is actually a global | 1127 // the map check so that we know that the object is actually a global |
1124 // object. | 1128 // object. |
1125 if (current->IsJSGlobalProxy()) { | 1129 if (current->IsJSGlobalProxy()) { |
1126 __ CheckAccessGlobalProxy(reg, scratch2, miss); | 1130 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
1127 } | 1131 } |
1128 reg = holder_reg; // From now on the object will be in holder_reg. | 1132 reg = holder_reg; // From now on the object will be in holder_reg. |
1129 | 1133 |
1130 if (heap()->InNewSpace(*prototype)) { | 1134 if (heap()->InNewSpace(*prototype)) { |
(...skipping 10 matching lines...) Expand all Loading... |
1141 __ str(reg, MemOperand(sp)); | 1145 __ str(reg, MemOperand(sp)); |
1142 } | 1146 } |
1143 | 1147 |
1144 // Go to the next object in the prototype chain. | 1148 // Go to the next object in the prototype chain. |
1145 current = prototype; | 1149 current = prototype; |
1146 } | 1150 } |
1147 | 1151 |
1148 // Log the check depth. | 1152 // Log the check depth. |
1149 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 1153 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); |
1150 | 1154 |
1151 // Check the holder map. | 1155 Handle<Map> current_map(current->map()); |
1152 __ CheckMap(reg, scratch1, Handle<Map>(current->map()), miss, | 1156 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { |
1153 DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); | 1157 // Check the holder map. |
| 1158 __ CheckMap(reg, scratch1, Handle<Map>(current->map()), miss, |
| 1159 DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
| 1160 } |
1154 | 1161 |
1155 // Perform security check for access to the global object. | 1162 // Perform security check for access to the global object. |
1156 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1163 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
1157 if (holder->IsJSGlobalProxy()) { | 1164 if (holder->IsJSGlobalProxy()) { |
1158 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1165 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
1159 } | 1166 } |
1160 | 1167 |
1161 // If we've skipped any global objects, it's not enough to verify that | 1168 // If we've skipped any global objects, it's not enough to verify that |
1162 // their maps haven't changed. We also need to check that the property | 1169 // their maps haven't changed. We also need to check that the property |
1163 // cell for the property is still empty. | 1170 // cell for the property is still empty. |
(...skipping 1811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2975 } | 2982 } |
2976 | 2983 |
2977 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 2984 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
2978 __ Jump(ic, RelocInfo::CODE_TARGET); | 2985 __ Jump(ic, RelocInfo::CODE_TARGET); |
2979 | 2986 |
2980 // Return the generated code. | 2987 // Return the generated code. |
2981 return GetCode(Code::NORMAL, factory()->empty_string()); | 2988 return GetCode(Code::NORMAL, factory()->empty_string()); |
2982 } | 2989 } |
2983 | 2990 |
2984 | 2991 |
2985 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( | 2992 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( |
2986 MapHandleList* receiver_maps, | 2993 MapHandleList* receiver_maps, |
2987 CodeHandleList* handler_ics) { | 2994 CodeHandleList* handlers, |
2988 // ----------- S t a t e ------------- | 2995 Handle<String> name) { |
2989 // -- lr : return address | |
2990 // -- r0 : key | |
2991 // -- r1 : receiver | |
2992 // ----------------------------------- | |
2993 Label miss; | 2996 Label miss; |
2994 __ JumpIfSmi(r1, &miss); | 2997 __ JumpIfSmi(receiver(), &miss); |
2995 | 2998 |
2996 int receiver_count = receiver_maps->length(); | 2999 int receiver_count = receiver_maps->length(); |
2997 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 3000 __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); |
2998 for (int current = 0; current < receiver_count; ++current) { | 3001 for (int current = 0; current < receiver_count; ++current) { |
2999 __ mov(ip, Operand(receiver_maps->at(current))); | 3002 __ mov(ip, Operand(receiver_maps->at(current))); |
3000 __ cmp(r2, ip); | 3003 __ cmp(scratch1(), ip); |
3001 __ Jump(handler_ics->at(current), RelocInfo::CODE_TARGET, eq); | 3004 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq); |
3002 } | 3005 } |
3003 | 3006 |
3004 __ bind(&miss); | 3007 __ bind(&miss); |
3005 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 3008 GenerateLoadMiss(masm(), kind()); |
3006 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); | |
3007 | 3009 |
3008 // Return the generated code. | 3010 // Return the generated code. |
3009 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | 3011 InlineCacheState state = |
| 3012 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; |
| 3013 return GetCode(type, name, state); |
3010 } | 3014 } |
3011 | 3015 |
3012 | 3016 |
3013 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 3017 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
3014 int index, | 3018 int index, |
3015 Handle<Map> transition, | 3019 Handle<Map> transition, |
3016 Handle<String> name) { | 3020 Handle<String> name) { |
3017 // ----------- S t a t e ------------- | 3021 // ----------- S t a t e ------------- |
3018 // -- r0 : value | 3022 // -- r0 : value |
3019 // -- r1 : name | 3023 // -- r1 : name |
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4054 __ Jump(ic_slow, RelocInfo::CODE_TARGET); | 4058 __ Jump(ic_slow, RelocInfo::CODE_TARGET); |
4055 } | 4059 } |
4056 } | 4060 } |
4057 | 4061 |
4058 | 4062 |
4059 #undef __ | 4063 #undef __ |
4060 | 4064 |
4061 } } // namespace v8::internal | 4065 } } // namespace v8::internal |
4062 | 4066 |
4063 #endif // V8_TARGET_ARCH_ARM | 4067 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |