1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_HEAP_PAGED_SPACES_INL_H_
6#define V8_HEAP_PAGED_SPACES_INL_H_
7
8#include "src/common/globals.h"
9#include "src/heap/heap-inl.h"
10#include "src/heap/incremental-marking.h"
11#include "src/heap/paged-spaces.h"
12#include "src/objects/heap-object.h"
13#include "src/objects/objects-inl.h"
14
15namespace v8 {
16namespace internal {
17
18// -----------------------------------------------------------------------------
19// PagedSpaceObjectIterator
20
21HeapObject PagedSpaceObjectIterator::Next() {
22  do {
23    HeapObject next_obj = FromCurrentPage();
24    if (!next_obj.is_null()) return next_obj;
25  } while (AdvanceToNextPage());
26  return HeapObject();
27}
28
29HeapObject PagedSpaceObjectIterator::FromCurrentPage() {
30  while (cur_addr_ != cur_end_) {
31    HeapObject obj = HeapObject::FromAddress(cur_addr_);
32    const int obj_size = obj.Size(cage_base());
33    cur_addr_ += obj_size;
34    DCHECK_LE(cur_addr_, cur_end_);
35    if (!obj.IsFreeSpaceOrFiller(cage_base())) {
36      if (obj.IsCode(cage_base())) {
37        DCHECK_EQ(space_->identity(), CODE_SPACE);
38        DCHECK_CODEOBJECT_SIZE(obj_size, space_);
39      } else {
40        DCHECK_OBJECT_SIZE(obj_size);
41      }
42      return obj;
43    }
44  }
45  return HeapObject();
46}
47
48bool PagedSpace::Contains(Address addr) const {
49  if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) {
50    return true;
51  }
52  return Page::FromAddress(addr)->owner() == this;
53}
54
55bool PagedSpace::Contains(Object o) const {
56  if (!o.IsHeapObject()) return false;
57  return Page::FromAddress(o.ptr())->owner() == this;
58}
59
60void PagedSpace::UnlinkFreeListCategories(Page* page) {
61  DCHECK_EQ(this, page->owner());
62  page->ForAllFreeListCategories([this](FreeListCategory* category) {
63    free_list()->RemoveCategory(category);
64  });
65}
66
67size_t PagedSpace::RelinkFreeListCategories(Page* page) {
68  DCHECK_EQ(this, page->owner());
69  size_t added = 0;
70  page->ForAllFreeListCategories([this, &added](FreeListCategory* category) {
71    added += category->available();
72    category->Relink(free_list());
73  });
74
75  DCHECK_IMPLIES(!page->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE),
76                 page->AvailableInFreeList() ==
77                     page->AvailableInFreeListFromAllocatedBytes());
78  return added;
79}
80
81bool PagedSpace::TryFreeLast(Address object_address, int object_size) {
82  if (allocation_info_->top() != kNullAddress) {
83    return allocation_info_->DecrementTopIfAdjacent(object_address,
84                                                    object_size);
85  }
86  return false;
87}
88
89}  // namespace internal
90}  // namespace v8
91
92#endif  // V8_HEAP_PAGED_SPACES_INL_H_
93