| OLD | NEW | 
|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 193 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 204           return GetVisitorIdForSize(kVisitStruct, | 204           return GetVisitorIdForSize(kVisitStruct, | 
| 205                                      kVisitStructGeneric, | 205                                      kVisitStructGeneric, | 
| 206                                      instance_size); | 206                                      instance_size); | 
| 207 | 207 | 
| 208     default: | 208     default: | 
| 209       UNREACHABLE(); | 209       UNREACHABLE(); | 
| 210       return kVisitorIdCount; | 210       return kVisitorIdCount; | 
| 211   } | 211   } | 
| 212 } | 212 } | 
| 213 | 213 | 
|  | 214 | 
|  | 215 template <class T> | 
|  | 216 struct WeakListVisitor; | 
|  | 217 | 
|  | 218 | 
|  | 219 template <class T> | 
|  | 220 Object* VisitWeakList(Heap* heap, | 
|  | 221                       Object* list, | 
|  | 222                       WeakObjectRetainer* retainer, | 
|  | 223                       bool record_slots) { | 
|  | 224   Object* undefined = heap->undefined_value(); | 
|  | 225   Object* head = undefined; | 
|  | 226   T* tail = NULL; | 
|  | 227   MarkCompactCollector* collector = heap->mark_compact_collector(); | 
|  | 228   while (list != undefined) { | 
|  | 229     // Check whether to keep the candidate in the list. | 
|  | 230     T* candidate = reinterpret_cast<T*>(list); | 
|  | 231     Object* retained = retainer->RetainAs(list); | 
|  | 232     if (retained != NULL) { | 
|  | 233       if (head == undefined) { | 
|  | 234         // First element in the list. | 
|  | 235         head = retained; | 
|  | 236       } else { | 
|  | 237         // Subsequent elements in the list. | 
|  | 238         ASSERT(tail != NULL); | 
|  | 239         WeakListVisitor<T>::SetWeakNext(tail, retained); | 
|  | 240         if (record_slots) { | 
|  | 241           Object** next_slot = | 
|  | 242             HeapObject::RawField(tail, WeakListVisitor<T>::WeakNextOffset()); | 
|  | 243           collector->RecordSlot(next_slot, next_slot, retained); | 
|  | 244         } | 
|  | 245       } | 
|  | 246       // Retained object is new tail. | 
|  | 247       ASSERT(!retained->IsUndefined()); | 
|  | 248       candidate = reinterpret_cast<T*>(retained); | 
|  | 249       tail = candidate; | 
|  | 250 | 
|  | 251 | 
|  | 252       // tail is a live object, visit it. | 
|  | 253       WeakListVisitor<T>::VisitLiveObject( | 
|  | 254           heap, tail, retainer, record_slots); | 
|  | 255     } else { | 
|  | 256       WeakListVisitor<T>::VisitPhantomObject(heap, candidate); | 
|  | 257     } | 
|  | 258 | 
|  | 259     // Move to next element in the list. | 
|  | 260     list = WeakListVisitor<T>::WeakNext(candidate); | 
|  | 261   } | 
|  | 262 | 
|  | 263   // Terminate the list if there is one or more elements. | 
|  | 264   if (tail != NULL) { | 
|  | 265     WeakListVisitor<T>::SetWeakNext(tail, undefined); | 
|  | 266   } | 
|  | 267   return head; | 
|  | 268 } | 
|  | 269 | 
|  | 270 | 
|  | 271 template <class T> | 
|  | 272 static void ClearWeakList(Heap* heap, | 
|  | 273                           Object* list) { | 
|  | 274   Object* undefined = heap->undefined_value(); | 
|  | 275   while (list != undefined) { | 
|  | 276     T* candidate = reinterpret_cast<T*>(list); | 
|  | 277     list = WeakListVisitor<T>::WeakNext(candidate); | 
|  | 278     WeakListVisitor<T>::SetWeakNext(candidate, undefined); | 
|  | 279   } | 
|  | 280 } | 
|  | 281 | 
|  | 282 | 
|  | 283 template<> | 
|  | 284 struct WeakListVisitor<JSFunction> { | 
|  | 285   static void SetWeakNext(JSFunction* function, Object* next) { | 
|  | 286     function->set_next_function_link(next); | 
|  | 287   } | 
|  | 288 | 
|  | 289   static Object* WeakNext(JSFunction* function) { | 
|  | 290     return function->next_function_link(); | 
|  | 291   } | 
|  | 292 | 
|  | 293   static int WeakNextOffset() { | 
|  | 294     return JSFunction::kNextFunctionLinkOffset; | 
|  | 295   } | 
|  | 296 | 
|  | 297   static void VisitLiveObject(Heap*, JSFunction*, | 
|  | 298                               WeakObjectRetainer*, bool) { | 
|  | 299   } | 
|  | 300 | 
|  | 301   static void VisitPhantomObject(Heap*, JSFunction*) { | 
|  | 302   } | 
|  | 303 }; | 
|  | 304 | 
|  | 305 | 
|  | 306 template<> | 
|  | 307 struct WeakListVisitor<Code> { | 
|  | 308   static void SetWeakNext(Code* code, Object* next) { | 
|  | 309     code->set_next_code_link(next); | 
|  | 310   } | 
|  | 311 | 
|  | 312   static Object* WeakNext(Code* code) { | 
|  | 313     return code->next_code_link(); | 
|  | 314   } | 
|  | 315 | 
|  | 316   static int WeakNextOffset() { | 
|  | 317     return Code::kNextCodeLinkOffset; | 
|  | 318   } | 
|  | 319 | 
|  | 320   static void VisitLiveObject(Heap*, Code*, | 
|  | 321                               WeakObjectRetainer*, bool) { | 
|  | 322   } | 
|  | 323 | 
|  | 324   static void VisitPhantomObject(Heap*, Code*) { | 
|  | 325   } | 
|  | 326 }; | 
|  | 327 | 
|  | 328 | 
|  | 329 template<> | 
|  | 330 struct WeakListVisitor<Context> { | 
|  | 331   static void SetWeakNext(Context* context, Object* next) { | 
|  | 332     context->set(Context::NEXT_CONTEXT_LINK, | 
|  | 333                  next, | 
|  | 334                  UPDATE_WRITE_BARRIER); | 
|  | 335   } | 
|  | 336 | 
|  | 337   static Object* WeakNext(Context* context) { | 
|  | 338     return context->get(Context::NEXT_CONTEXT_LINK); | 
|  | 339   } | 
|  | 340 | 
|  | 341   static void VisitLiveObject(Heap* heap, | 
|  | 342                               Context* context, | 
|  | 343                               WeakObjectRetainer* retainer, | 
|  | 344                               bool record_slots) { | 
|  | 345     // Process the three weak lists linked off the context. | 
|  | 346     DoWeakList<JSFunction>(heap, context, retainer, record_slots, | 
|  | 347         Context::OPTIMIZED_FUNCTIONS_LIST); | 
|  | 348     DoWeakList<Code>(heap, context, retainer, record_slots, | 
|  | 349         Context::OPTIMIZED_CODE_LIST); | 
|  | 350     DoWeakList<Code>(heap, context, retainer, record_slots, | 
|  | 351         Context::DEOPTIMIZED_CODE_LIST); | 
|  | 352   } | 
|  | 353 | 
|  | 354   template<class T> | 
|  | 355   static void DoWeakList(Heap* heap, | 
|  | 356                          Context* context, | 
|  | 357                          WeakObjectRetainer* retainer, | 
|  | 358                          bool record_slots, | 
|  | 359                          int index) { | 
|  | 360     // Visit the weak list, removing dead intermediate elements. | 
|  | 361     Object* list_head = VisitWeakList<T>(heap, context->get(index), retainer, | 
|  | 362         record_slots); | 
|  | 363 | 
|  | 364     // Update the list head. | 
|  | 365     context->set(index, list_head, UPDATE_WRITE_BARRIER); | 
|  | 366 | 
|  | 367     if (record_slots) { | 
|  | 368       // Record the updated slot if necessary. | 
|  | 369       Object** head_slot = HeapObject::RawField( | 
|  | 370           context, FixedArray::SizeFor(index)); | 
|  | 371       heap->mark_compact_collector()->RecordSlot( | 
|  | 372           head_slot, head_slot, list_head); | 
|  | 373     } | 
|  | 374   } | 
|  | 375 | 
|  | 376   static void VisitPhantomObject(Heap* heap, Context* context) { | 
|  | 377     ClearWeakList<JSFunction>(heap, | 
|  | 378         context->get(Context::OPTIMIZED_FUNCTIONS_LIST)); | 
|  | 379     ClearWeakList<Code>(heap, context->get(Context::OPTIMIZED_CODE_LIST)); | 
|  | 380     ClearWeakList<Code>(heap, context->get(Context::DEOPTIMIZED_CODE_LIST)); | 
|  | 381   } | 
|  | 382 | 
|  | 383   static int WeakNextOffset() { | 
|  | 384     return FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK); | 
|  | 385   } | 
|  | 386 }; | 
|  | 387 | 
|  | 388 | 
|  | 389 template<> | 
|  | 390 struct WeakListVisitor<JSArrayBufferView> { | 
|  | 391   static void SetWeakNext(JSArrayBufferView* obj, Object* next) { | 
|  | 392     obj->set_weak_next(next); | 
|  | 393   } | 
|  | 394 | 
|  | 395   static Object* WeakNext(JSArrayBufferView* obj) { | 
|  | 396     return obj->weak_next(); | 
|  | 397   } | 
|  | 398 | 
|  | 399   static void VisitLiveObject(Heap*, | 
|  | 400                               JSArrayBufferView* obj, | 
|  | 401                               WeakObjectRetainer* retainer, | 
|  | 402                               bool record_slots) {} | 
|  | 403 | 
|  | 404   static void VisitPhantomObject(Heap*, JSArrayBufferView*) {} | 
|  | 405 | 
|  | 406   static int WeakNextOffset() { | 
|  | 407     return JSArrayBufferView::kWeakNextOffset; | 
|  | 408   } | 
|  | 409 }; | 
|  | 410 | 
|  | 411 | 
|  | 412 template<> | 
|  | 413 struct WeakListVisitor<JSArrayBuffer> { | 
|  | 414   static void SetWeakNext(JSArrayBuffer* obj, Object* next) { | 
|  | 415     obj->set_weak_next(next); | 
|  | 416   } | 
|  | 417 | 
|  | 418   static Object* WeakNext(JSArrayBuffer* obj) { | 
|  | 419     return obj->weak_next(); | 
|  | 420   } | 
|  | 421 | 
|  | 422   static void VisitLiveObject(Heap* heap, | 
|  | 423                               JSArrayBuffer* array_buffer, | 
|  | 424                               WeakObjectRetainer* retainer, | 
|  | 425                               bool record_slots) { | 
|  | 426     Object* typed_array_obj = | 
|  | 427         VisitWeakList<JSArrayBufferView>( | 
|  | 428             heap, | 
|  | 429             array_buffer->weak_first_view(), | 
|  | 430             retainer, record_slots); | 
|  | 431     array_buffer->set_weak_first_view(typed_array_obj); | 
|  | 432     if (typed_array_obj != heap->undefined_value() && record_slots) { | 
|  | 433       Object** slot = HeapObject::RawField( | 
|  | 434           array_buffer, JSArrayBuffer::kWeakFirstViewOffset); | 
|  | 435       heap->mark_compact_collector()->RecordSlot(slot, slot, typed_array_obj); | 
|  | 436     } | 
|  | 437   } | 
|  | 438 | 
|  | 439   static void VisitPhantomObject(Heap* heap, JSArrayBuffer* phantom) { | 
|  | 440     Runtime::FreeArrayBuffer(heap->isolate(), phantom); | 
|  | 441   } | 
|  | 442 | 
|  | 443   static int WeakNextOffset() { | 
|  | 444     return JSArrayBuffer::kWeakNextOffset; | 
|  | 445   } | 
|  | 446 }; | 
|  | 447 | 
|  | 448 | 
|  | 449 template<> | 
|  | 450 struct WeakListVisitor<AllocationSite> { | 
|  | 451   static void SetWeakNext(AllocationSite* obj, Object* next) { | 
|  | 452     obj->set_weak_next(next); | 
|  | 453   } | 
|  | 454 | 
|  | 455   static Object* WeakNext(AllocationSite* obj) { | 
|  | 456     return obj->weak_next(); | 
|  | 457   } | 
|  | 458 | 
|  | 459   static void VisitLiveObject(Heap* heap, | 
|  | 460                               AllocationSite* site, | 
|  | 461                               WeakObjectRetainer* retainer, | 
|  | 462                               bool record_slots) {} | 
|  | 463 | 
|  | 464   static void VisitPhantomObject(Heap* heap, AllocationSite* phantom) {} | 
|  | 465 | 
|  | 466   static int WeakNextOffset() { | 
|  | 467     return AllocationSite::kWeakNextOffset; | 
|  | 468   } | 
|  | 469 }; | 
|  | 470 | 
|  | 471 | 
|  | 472 template Object* VisitWeakList<Code>( | 
|  | 473     Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); | 
|  | 474 | 
|  | 475 | 
|  | 476 template Object* VisitWeakList<JSFunction>( | 
|  | 477     Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); | 
|  | 478 | 
|  | 479 | 
|  | 480 template Object* VisitWeakList<Context>( | 
|  | 481     Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); | 
|  | 482 | 
|  | 483 | 
|  | 484 template Object* VisitWeakList<JSArrayBuffer>( | 
|  | 485     Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); | 
|  | 486 | 
|  | 487 | 
|  | 488 template Object* VisitWeakList<AllocationSite>( | 
|  | 489     Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); | 
|  | 490 | 
| 214 } }  // namespace v8::internal | 491 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|