OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/ic/ic.h" | 7 #include "src/ic/ic.h" |
8 #include "src/ic/ic-state.h" | 8 #include "src/ic/ic-state.h" |
9 #include "src/objects.h" | 9 #include "src/objects.h" |
10 #include "src/type-feedback-vector-inl.h" | 10 #include "src/type-feedback-vector-inl.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 Isolate* isolate, Handle<TypeFeedbackVector> vector) { | 125 Isolate* isolate, Handle<TypeFeedbackVector> vector) { |
126 Handle<TypeFeedbackVector> result; | 126 Handle<TypeFeedbackVector> result; |
127 result = Handle<TypeFeedbackVector>::cast( | 127 result = Handle<TypeFeedbackVector>::cast( |
128 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); | 128 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); |
129 return result; | 129 return result; |
130 } | 130 } |
131 | 131 |
132 | 132 |
133 // This logic is copied from | 133 // This logic is copied from |
134 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. | 134 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. |
135 // TODO(mvstanton): with weak handling of all vector ics, this logic should | 135 static bool ClearLogic(Heap* heap, int ic_age) { |
136 // actually be completely eliminated and we no longer need to clear the | |
137 // vector ICs. | |
138 static bool ClearLogic(Heap* heap, int ic_age, Code::Kind kind, | |
139 InlineCacheState state) { | |
140 if (FLAG_cleanup_code_caches_at_gc && | 136 if (FLAG_cleanup_code_caches_at_gc && |
141 (kind == Code::CALL_IC || heap->flush_monomorphic_ics() || | 137 (heap->flush_monomorphic_ics() || |
142 // TODO(mvstanton): is this ic_age granular enough? it comes from | 138 // TODO(mvstanton): is this ic_age granular enough? it comes from |
143 // the SharedFunctionInfo which may change on a different schedule | 139 // the SharedFunctionInfo which may change on a different schedule |
144 // than ic targets. | 140 // than ic targets. |
145 // ic_age != heap->global_ic_age() || | 141 // ic_age != heap->global_ic_age() || |
146 // is_invalidated_weak_stub || | 142 // is_invalidated_weak_stub || |
147 heap->isolate()->serializer_enabled())) { | 143 heap->isolate()->serializer_enabled())) { |
148 return true; | 144 return true; |
149 } | 145 } |
150 return false; | 146 return false; |
151 } | 147 } |
(...skipping 12 matching lines...) Expand all Loading... |
164 InstanceType instance_type = | 160 InstanceType instance_type = |
165 HeapObject::cast(obj)->map()->instance_type(); | 161 HeapObject::cast(obj)->map()->instance_type(); |
166 // AllocationSites are exempt from clearing. They don't store Maps | 162 // AllocationSites are exempt from clearing. They don't store Maps |
167 // or Code pointers which can cause memory leaks if not cleared | 163 // or Code pointers which can cause memory leaks if not cleared |
168 // regularly. | 164 // regularly. |
169 if (instance_type != ALLOCATION_SITE_TYPE) { | 165 if (instance_type != ALLOCATION_SITE_TYPE) { |
170 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); | 166 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); |
171 } | 167 } |
172 } | 168 } |
173 } | 169 } |
| 170 } |
174 | 171 |
175 slots = ICSlots(); | |
176 if (slots == 0) return; | |
177 | 172 |
178 // Now clear vector-based ICs. | 173 void TypeFeedbackVector::ClearICSlotsImpl(SharedFunctionInfo* shared, |
179 // Try and pass the containing code (the "host"). | 174 bool force_clear) { |
180 Heap* heap = isolate->heap(); | 175 Heap* heap = GetIsolate()->heap(); |
181 Code* host = shared->code(); | 176 |
182 // I'm not sure yet if this ic age is the correct one. | 177 // I'm not sure yet if this ic age is the correct one. |
183 int ic_age = shared->ic_age(); | 178 int ic_age = shared->ic_age(); |
| 179 |
| 180 if (!force_clear && !ClearLogic(heap, ic_age)) return; |
| 181 |
| 182 int slots = ICSlots(); |
| 183 Code* host = shared->code(); |
| 184 Object* uninitialized_sentinel = |
| 185 TypeFeedbackVector::RawUninitializedSentinel(heap); |
184 for (int i = 0; i < slots; i++) { | 186 for (int i = 0; i < slots; i++) { |
185 FeedbackVectorICSlot slot(i); | 187 FeedbackVectorICSlot slot(i); |
186 Object* obj = Get(slot); | 188 Object* obj = Get(slot); |
187 if (obj != uninitialized_sentinel) { | 189 if (obj != uninitialized_sentinel) { |
188 Code::Kind kind = GetKind(slot); | 190 Code::Kind kind = GetKind(slot); |
189 if (kind == Code::CALL_IC) { | 191 if (kind == Code::CALL_IC) { |
190 CallICNexus nexus(this, slot); | 192 CallICNexus nexus(this, slot); |
191 if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) { | 193 nexus.Clear(host); |
192 nexus.Clear(host); | |
193 } | |
194 } else if (kind == Code::LOAD_IC) { | 194 } else if (kind == Code::LOAD_IC) { |
195 LoadICNexus nexus(this, slot); | 195 LoadICNexus nexus(this, slot); |
196 if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) { | 196 nexus.Clear(host); |
197 nexus.Clear(host); | |
198 } | |
199 } else if (kind == Code::KEYED_LOAD_IC) { | 197 } else if (kind == Code::KEYED_LOAD_IC) { |
200 KeyedLoadICNexus nexus(this, slot); | 198 KeyedLoadICNexus nexus(this, slot); |
201 if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) { | 199 nexus.Clear(host); |
202 nexus.Clear(host); | |
203 } | |
204 } | 200 } |
205 } | 201 } |
206 } | 202 } |
207 } | 203 } |
208 | 204 |
209 | 205 |
210 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { | 206 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { |
211 Isolate* isolate = GetIsolate(); | 207 Isolate* isolate = GetIsolate(); |
212 Handle<Object> feedback = handle(GetFeedback(), isolate); | 208 Handle<Object> feedback = handle(GetFeedback(), isolate); |
213 if (!feedback->IsFixedArray() || | 209 if (!feedback->IsFixedArray() || |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 return UNINITIALIZED; | 274 return UNINITIALIZED; |
279 } | 275 } |
280 | 276 |
281 | 277 |
282 InlineCacheState CallICNexus::StateFromFeedback() const { | 278 InlineCacheState CallICNexus::StateFromFeedback() const { |
283 Isolate* isolate = GetIsolate(); | 279 Isolate* isolate = GetIsolate(); |
284 Object* feedback = GetFeedback(); | 280 Object* feedback = GetFeedback(); |
285 | 281 |
286 if (feedback == *vector()->MegamorphicSentinel(isolate)) { | 282 if (feedback == *vector()->MegamorphicSentinel(isolate)) { |
287 return GENERIC; | 283 return GENERIC; |
288 } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) { | 284 } else if (feedback->IsAllocationSite() || feedback->IsWeakCell()) { |
289 return MONOMORPHIC; | 285 return MONOMORPHIC; |
290 } | 286 } |
291 | 287 |
292 CHECK(feedback == *vector()->UninitializedSentinel(isolate)); | 288 CHECK(feedback == *vector()->UninitializedSentinel(isolate)); |
293 return UNINITIALIZED; | 289 return UNINITIALIZED; |
294 } | 290 } |
295 | 291 |
296 | 292 |
297 void CallICNexus::Clear(Code* host) { CallIC::Clear(GetIsolate(), host, this); } | 293 void CallICNexus::Clear(Code* host) { CallIC::Clear(GetIsolate(), host, this); } |
298 | 294 |
(...skipping 13 matching lines...) Expand all Loading... |
312 } | 308 } |
313 | 309 |
314 | 310 |
315 void CallICNexus::ConfigureUninitialized() { | 311 void CallICNexus::ConfigureUninitialized() { |
316 SetFeedback(*vector()->UninitializedSentinel(GetIsolate()), | 312 SetFeedback(*vector()->UninitializedSentinel(GetIsolate()), |
317 SKIP_WRITE_BARRIER); | 313 SKIP_WRITE_BARRIER); |
318 } | 314 } |
319 | 315 |
320 | 316 |
321 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { | 317 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { |
322 SetFeedback(*function); | 318 Handle<WeakCell> new_cell = GetIsolate()->factory()->NewWeakCell(function); |
| 319 SetFeedback(*new_cell); |
323 } | 320 } |
324 | 321 |
325 | 322 |
326 void KeyedLoadICNexus::ConfigureMegamorphic() { | 323 void KeyedLoadICNexus::ConfigureMegamorphic() { |
327 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); | 324 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); |
328 } | 325 } |
329 | 326 |
330 | 327 |
331 void LoadICNexus::ConfigureMegamorphic() { | 328 void LoadICNexus::ConfigureMegamorphic() { |
332 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); | 329 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 if (feedback->IsFixedArray()) { | 504 if (feedback->IsFixedArray()) { |
508 FixedArray* array = FixedArray::cast(feedback); | 505 FixedArray* array = FixedArray::cast(feedback); |
509 DCHECK(array->length() >= 3); | 506 DCHECK(array->length() >= 3); |
510 Object* name = array->get(0); | 507 Object* name = array->get(0); |
511 if (name->IsName()) return Name::cast(name); | 508 if (name->IsName()) return Name::cast(name); |
512 } | 509 } |
513 return NULL; | 510 return NULL; |
514 } | 511 } |
515 } | 512 } |
516 } // namespace v8::internal | 513 } // namespace v8::internal |
OLD | NEW |