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

Side by Side Diff: src/objects-visiting.cc

Issue 282493004: Simplified slot buffer logic during weak list visiting. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 months 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/objects-visiting.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 "v8.h" 5 #include "v8.h"
6 6
7 #include "ic-inl.h" 7 #include "ic-inl.h"
8 #include "objects-visiting.h" 8 #include "objects-visiting.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 kVisitStructGeneric, 184 kVisitStructGeneric,
185 instance_size); 185 instance_size);
186 186
187 default: 187 default:
188 UNREACHABLE(); 188 UNREACHABLE();
189 return kVisitorIdCount; 189 return kVisitorIdCount;
190 } 190 }
191 } 191 }
192 192
193 193
194 // We don't record weak slots during marking or scavenges. Instead we do it
195 // once when we complete mark-compact cycle. Note that write barrier has no
196 // effect if we are already in the middle of compacting mark-sweep cycle and we
197 // have to record slots manually.
198 static bool MustRecordSlots(Heap* heap) {
199 return heap->gc_state() == Heap::MARK_COMPACT &&
200 heap->mark_compact_collector()->is_compacting();
201 }
202
203
194 template <class T> 204 template <class T>
195 struct WeakListVisitor; 205 struct WeakListVisitor;
196 206
197 207
198 template <class T> 208 template <class T>
199 Object* VisitWeakList(Heap* heap, 209 Object* VisitWeakList(Heap* heap,
200 Object* list, 210 Object* list,
201 WeakObjectRetainer* retainer, 211 WeakObjectRetainer* retainer) {
202 bool record_slots) {
203 Object* undefined = heap->undefined_value(); 212 Object* undefined = heap->undefined_value();
204 Object* head = undefined; 213 Object* head = undefined;
205 T* tail = NULL; 214 T* tail = NULL;
206 MarkCompactCollector* collector = heap->mark_compact_collector(); 215 MarkCompactCollector* collector = heap->mark_compact_collector();
216 bool record_slots = MustRecordSlots(heap);
207 while (list != undefined) { 217 while (list != undefined) {
208 // Check whether to keep the candidate in the list. 218 // Check whether to keep the candidate in the list.
209 T* candidate = reinterpret_cast<T*>(list); 219 T* candidate = reinterpret_cast<T*>(list);
210 Object* retained = retainer->RetainAs(list); 220 Object* retained = retainer->RetainAs(list);
211 if (retained != NULL) { 221 if (retained != NULL) {
212 if (head == undefined) { 222 if (head == undefined) {
213 // First element in the list. 223 // First element in the list.
214 head = retained; 224 head = retained;
215 } else { 225 } else {
216 // Subsequent elements in the list. 226 // Subsequent elements in the list.
217 ASSERT(tail != NULL); 227 ASSERT(tail != NULL);
218 WeakListVisitor<T>::SetWeakNext(tail, retained); 228 WeakListVisitor<T>::SetWeakNext(tail, retained);
219 if (record_slots) { 229 if (record_slots) {
220 Object** next_slot = 230 Object** next_slot =
221 HeapObject::RawField(tail, WeakListVisitor<T>::WeakNextOffset()); 231 HeapObject::RawField(tail, WeakListVisitor<T>::WeakNextOffset());
222 collector->RecordSlot(next_slot, next_slot, retained); 232 collector->RecordSlot(next_slot, next_slot, retained);
223 } 233 }
224 } 234 }
225 // Retained object is new tail. 235 // Retained object is new tail.
226 ASSERT(!retained->IsUndefined()); 236 ASSERT(!retained->IsUndefined());
227 candidate = reinterpret_cast<T*>(retained); 237 candidate = reinterpret_cast<T*>(retained);
228 tail = candidate; 238 tail = candidate;
229 239
230 240
231 // tail is a live object, visit it. 241 // tail is a live object, visit it.
232 WeakListVisitor<T>::VisitLiveObject( 242 WeakListVisitor<T>::VisitLiveObject(heap, tail, retainer);
233 heap, tail, retainer, record_slots);
234 } else { 243 } else {
235 WeakListVisitor<T>::VisitPhantomObject(heap, candidate); 244 WeakListVisitor<T>::VisitPhantomObject(heap, candidate);
236 } 245 }
237 246
238 // Move to next element in the list. 247 // Move to next element in the list.
239 list = WeakListVisitor<T>::WeakNext(candidate); 248 list = WeakListVisitor<T>::WeakNext(candidate);
240 } 249 }
241 250
242 // Terminate the list if there is one or more elements. 251 // Terminate the list if there is one or more elements.
243 if (tail != NULL) { 252 if (tail != NULL) {
(...skipping 22 matching lines...) Expand all
266 } 275 }
267 276
268 static Object* WeakNext(JSFunction* function) { 277 static Object* WeakNext(JSFunction* function) {
269 return function->next_function_link(); 278 return function->next_function_link();
270 } 279 }
271 280
272 static int WeakNextOffset() { 281 static int WeakNextOffset() {
273 return JSFunction::kNextFunctionLinkOffset; 282 return JSFunction::kNextFunctionLinkOffset;
274 } 283 }
275 284
276 static void VisitLiveObject(Heap*, JSFunction*, 285 static void VisitLiveObject(Heap*, JSFunction*, WeakObjectRetainer*) {}
277 WeakObjectRetainer*, bool) {
278 }
279 286
280 static void VisitPhantomObject(Heap*, JSFunction*) { 287 static void VisitPhantomObject(Heap*, JSFunction*) {}
281 }
282 }; 288 };
283 289
284 290
285 template<> 291 template<>
286 struct WeakListVisitor<Code> { 292 struct WeakListVisitor<Code> {
287 static void SetWeakNext(Code* code, Object* next) { 293 static void SetWeakNext(Code* code, Object* next) {
288 code->set_next_code_link(next); 294 code->set_next_code_link(next);
289 } 295 }
290 296
291 static Object* WeakNext(Code* code) { 297 static Object* WeakNext(Code* code) {
292 return code->next_code_link(); 298 return code->next_code_link();
293 } 299 }
294 300
295 static int WeakNextOffset() { 301 static int WeakNextOffset() {
296 return Code::kNextCodeLinkOffset; 302 return Code::kNextCodeLinkOffset;
297 } 303 }
298 304
299 static void VisitLiveObject(Heap*, Code*, 305 static void VisitLiveObject(Heap*, Code*, WeakObjectRetainer*) {}
300 WeakObjectRetainer*, bool) {
301 }
302 306
303 static void VisitPhantomObject(Heap*, Code*) { 307 static void VisitPhantomObject(Heap*, Code*) {}
304 }
305 }; 308 };
306 309
307 310
308 template<> 311 template<>
309 struct WeakListVisitor<Context> { 312 struct WeakListVisitor<Context> {
310 static void SetWeakNext(Context* context, Object* next) { 313 static void SetWeakNext(Context* context, Object* next) {
311 context->set(Context::NEXT_CONTEXT_LINK, 314 context->set(Context::NEXT_CONTEXT_LINK,
312 next, 315 next,
313 UPDATE_WRITE_BARRIER); 316 UPDATE_WRITE_BARRIER);
314 } 317 }
315 318
316 static Object* WeakNext(Context* context) { 319 static Object* WeakNext(Context* context) {
317 return context->get(Context::NEXT_CONTEXT_LINK); 320 return context->get(Context::NEXT_CONTEXT_LINK);
318 } 321 }
319 322
323 static int WeakNextOffset() {
324 return FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK);
325 }
326
320 static void VisitLiveObject(Heap* heap, 327 static void VisitLiveObject(Heap* heap,
321 Context* context, 328 Context* context,
322 WeakObjectRetainer* retainer, 329 WeakObjectRetainer* retainer) {
323 bool record_slots) {
324 // Process the three weak lists linked off the context. 330 // Process the three weak lists linked off the context.
325 DoWeakList<JSFunction>(heap, context, retainer, record_slots, 331 DoWeakList<JSFunction>(heap, context, retainer,
326 Context::OPTIMIZED_FUNCTIONS_LIST); 332 Context::OPTIMIZED_FUNCTIONS_LIST);
327 DoWeakList<Code>(heap, context, retainer, record_slots, 333 DoWeakList<Code>(heap, context, retainer, Context::OPTIMIZED_CODE_LIST);
328 Context::OPTIMIZED_CODE_LIST); 334 DoWeakList<Code>(heap, context, retainer, Context::DEOPTIMIZED_CODE_LIST);
329 DoWeakList<Code>(heap, context, retainer, record_slots,
330 Context::DEOPTIMIZED_CODE_LIST);
331 } 335 }
332 336
333 template<class T> 337 template<class T>
334 static void DoWeakList(Heap* heap, 338 static void DoWeakList(Heap* heap,
335 Context* context, 339 Context* context,
336 WeakObjectRetainer* retainer, 340 WeakObjectRetainer* retainer,
337 bool record_slots,
338 int index) { 341 int index) {
339 // Visit the weak list, removing dead intermediate elements. 342 // Visit the weak list, removing dead intermediate elements.
340 Object* list_head = VisitWeakList<T>(heap, context->get(index), retainer, 343 Object* list_head = VisitWeakList<T>(heap, context->get(index), retainer);
341 record_slots);
342 344
343 // Update the list head. 345 // Update the list head.
344 context->set(index, list_head, UPDATE_WRITE_BARRIER); 346 context->set(index, list_head, UPDATE_WRITE_BARRIER);
345 347
346 if (record_slots) { 348 if (MustRecordSlots(heap)) {
347 // Record the updated slot if necessary. 349 // Record the updated slot if necessary.
348 Object** head_slot = HeapObject::RawField( 350 Object** head_slot = HeapObject::RawField(
349 context, FixedArray::SizeFor(index)); 351 context, FixedArray::SizeFor(index));
350 heap->mark_compact_collector()->RecordSlot( 352 heap->mark_compact_collector()->RecordSlot(
351 head_slot, head_slot, list_head); 353 head_slot, head_slot, list_head);
352 } 354 }
353 } 355 }
354 356
355 static void VisitPhantomObject(Heap* heap, Context* context) { 357 static void VisitPhantomObject(Heap* heap, Context* context) {
356 ClearWeakList<JSFunction>(heap, 358 ClearWeakList<JSFunction>(heap,
357 context->get(Context::OPTIMIZED_FUNCTIONS_LIST)); 359 context->get(Context::OPTIMIZED_FUNCTIONS_LIST));
358 ClearWeakList<Code>(heap, context->get(Context::OPTIMIZED_CODE_LIST)); 360 ClearWeakList<Code>(heap, context->get(Context::OPTIMIZED_CODE_LIST));
359 ClearWeakList<Code>(heap, context->get(Context::DEOPTIMIZED_CODE_LIST)); 361 ClearWeakList<Code>(heap, context->get(Context::DEOPTIMIZED_CODE_LIST));
360 } 362 }
361
362 static int WeakNextOffset() {
363 return FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK);
364 }
365 }; 363 };
366 364
367 365
368 template<> 366 template<>
369 struct WeakListVisitor<JSArrayBufferView> { 367 struct WeakListVisitor<JSArrayBufferView> {
370 static void SetWeakNext(JSArrayBufferView* obj, Object* next) { 368 static void SetWeakNext(JSArrayBufferView* obj, Object* next) {
371 obj->set_weak_next(next); 369 obj->set_weak_next(next);
372 } 370 }
373 371
374 static Object* WeakNext(JSArrayBufferView* obj) { 372 static Object* WeakNext(JSArrayBufferView* obj) {
375 return obj->weak_next(); 373 return obj->weak_next();
376 } 374 }
377 375
378 static void VisitLiveObject(Heap*,
379 JSArrayBufferView* obj,
380 WeakObjectRetainer* retainer,
381 bool record_slots) {}
382
383 static void VisitPhantomObject(Heap*, JSArrayBufferView*) {}
384
385 static int WeakNextOffset() { 376 static int WeakNextOffset() {
386 return JSArrayBufferView::kWeakNextOffset; 377 return JSArrayBufferView::kWeakNextOffset;
387 } 378 }
379
380 static void VisitLiveObject(Heap*, JSArrayBufferView*, WeakObjectRetainer*) {}
381
382 static void VisitPhantomObject(Heap*, JSArrayBufferView*) {}
388 }; 383 };
389 384
390 385
391 template<> 386 template<>
392 struct WeakListVisitor<JSArrayBuffer> { 387 struct WeakListVisitor<JSArrayBuffer> {
393 static void SetWeakNext(JSArrayBuffer* obj, Object* next) { 388 static void SetWeakNext(JSArrayBuffer* obj, Object* next) {
394 obj->set_weak_next(next); 389 obj->set_weak_next(next);
395 } 390 }
396 391
397 static Object* WeakNext(JSArrayBuffer* obj) { 392 static Object* WeakNext(JSArrayBuffer* obj) {
398 return obj->weak_next(); 393 return obj->weak_next();
399 } 394 }
400 395
396 static int WeakNextOffset() {
397 return JSArrayBuffer::kWeakNextOffset;
398 }
399
401 static void VisitLiveObject(Heap* heap, 400 static void VisitLiveObject(Heap* heap,
402 JSArrayBuffer* array_buffer, 401 JSArrayBuffer* array_buffer,
403 WeakObjectRetainer* retainer, 402 WeakObjectRetainer* retainer) {
404 bool record_slots) {
405 Object* typed_array_obj = 403 Object* typed_array_obj =
406 VisitWeakList<JSArrayBufferView>( 404 VisitWeakList<JSArrayBufferView>(
407 heap, 405 heap,
408 array_buffer->weak_first_view(), 406 array_buffer->weak_first_view(),
409 retainer, record_slots); 407 retainer);
410 array_buffer->set_weak_first_view(typed_array_obj); 408 array_buffer->set_weak_first_view(typed_array_obj);
411 if (typed_array_obj != heap->undefined_value() && record_slots) { 409 if (typed_array_obj != heap->undefined_value() && MustRecordSlots(heap)) {
412 Object** slot = HeapObject::RawField( 410 Object** slot = HeapObject::RawField(
413 array_buffer, JSArrayBuffer::kWeakFirstViewOffset); 411 array_buffer, JSArrayBuffer::kWeakFirstViewOffset);
414 heap->mark_compact_collector()->RecordSlot(slot, slot, typed_array_obj); 412 heap->mark_compact_collector()->RecordSlot(slot, slot, typed_array_obj);
415 } 413 }
416 } 414 }
417 415
418 static void VisitPhantomObject(Heap* heap, JSArrayBuffer* phantom) { 416 static void VisitPhantomObject(Heap* heap, JSArrayBuffer* phantom) {
419 Runtime::FreeArrayBuffer(heap->isolate(), phantom); 417 Runtime::FreeArrayBuffer(heap->isolate(), phantom);
420 } 418 }
421
422 static int WeakNextOffset() {
423 return JSArrayBuffer::kWeakNextOffset;
424 }
425 }; 419 };
426 420
427 421
428 template<> 422 template<>
429 struct WeakListVisitor<AllocationSite> { 423 struct WeakListVisitor<AllocationSite> {
430 static void SetWeakNext(AllocationSite* obj, Object* next) { 424 static void SetWeakNext(AllocationSite* obj, Object* next) {
431 obj->set_weak_next(next); 425 obj->set_weak_next(next);
432 } 426 }
433 427
434 static Object* WeakNext(AllocationSite* obj) { 428 static Object* WeakNext(AllocationSite* obj) {
435 return obj->weak_next(); 429 return obj->weak_next();
436 } 430 }
437 431
438 static void VisitLiveObject(Heap* heap,
439 AllocationSite* site,
440 WeakObjectRetainer* retainer,
441 bool record_slots) {}
442
443 static void VisitPhantomObject(Heap* heap, AllocationSite* phantom) {}
444
445 static int WeakNextOffset() { 432 static int WeakNextOffset() {
446 return AllocationSite::kWeakNextOffset; 433 return AllocationSite::kWeakNextOffset;
447 } 434 }
435
436 static void VisitLiveObject(Heap*, AllocationSite*, WeakObjectRetainer*) {}
437
438 static void VisitPhantomObject(Heap*, AllocationSite*) {}
448 }; 439 };
449 440
450 441
451 template Object* VisitWeakList<Code>( 442 template Object* VisitWeakList<Code>(
452 Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); 443 Heap* heap, Object* list, WeakObjectRetainer* retainer);
453 444
454 445
455 template Object* VisitWeakList<JSFunction>( 446 template Object* VisitWeakList<JSFunction>(
456 Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); 447 Heap* heap, Object* list, WeakObjectRetainer* retainer);
457 448
458 449
459 template Object* VisitWeakList<Context>( 450 template Object* VisitWeakList<Context>(
460 Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); 451 Heap* heap, Object* list, WeakObjectRetainer* retainer);
461 452
462 453
463 template Object* VisitWeakList<JSArrayBuffer>( 454 template Object* VisitWeakList<JSArrayBuffer>(
464 Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); 455 Heap* heap, Object* list, WeakObjectRetainer* retainer);
465 456
466 457
467 template Object* VisitWeakList<AllocationSite>( 458 template Object* VisitWeakList<AllocationSite>(
468 Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); 459 Heap* heap, Object* list, WeakObjectRetainer* retainer);
469 460
470 } } // namespace v8::internal 461 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects-visiting.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698