| 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 |