1// Copyright 2019 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#include "heap-constants.h"
6#include "src/common/globals.h"
7
8namespace d = v8::debug_helper;
9
10namespace v8 {
11namespace internal {
12namespace debug_helper_internal {
13
14std::string FindKnownObject(uintptr_t address,
15                            const d::HeapAddresses& heap_addresses) {
16  uintptr_t containing_page = address & ~i::kPageAlignmentMask;
17  uintptr_t offset_in_page = address & i::kPageAlignmentMask;
18
19  // If there's a match with a known page, then search only that page.
20  if (containing_page == heap_addresses.map_space_first_page) {
21    return FindKnownObjectInMapSpace(offset_in_page);
22  }
23  if (containing_page == heap_addresses.old_space_first_page) {
24    return FindKnownObjectInOldSpace(offset_in_page);
25  }
26  if (containing_page == heap_addresses.read_only_space_first_page) {
27    return FindKnownObjectInReadOnlySpace(offset_in_page);
28  }
29
30  // For any unknown pages, compile a list of things this object might be.
31  std::string result;
32  if (heap_addresses.map_space_first_page == 0) {
33    std::string sub_result = FindKnownObjectInMapSpace(offset_in_page);
34    if (!sub_result.empty()) {
35      result += "maybe " + sub_result;
36    }
37  }
38  if (heap_addresses.old_space_first_page == 0) {
39    std::string sub_result = FindKnownObjectInOldSpace(offset_in_page);
40    if (!sub_result.empty()) {
41      result = (result.empty() ? "" : result + ", ") + "maybe " + sub_result;
42    }
43  }
44  if (heap_addresses.read_only_space_first_page == 0) {
45    std::string sub_result = FindKnownObjectInReadOnlySpace(offset_in_page);
46    if (!sub_result.empty()) {
47      result = (result.empty() ? "" : result + ", ") + "maybe " + sub_result;
48    }
49  }
50
51  return result;
52}
53
54KnownInstanceType FindKnownMapInstanceTypes(
55    uintptr_t address, const d::HeapAddresses& heap_addresses) {
56  uintptr_t containing_page = address & ~i::kPageAlignmentMask;
57  uintptr_t offset_in_page = address & i::kPageAlignmentMask;
58
59  // If there's a match with a known page, then search only that page.
60  if (containing_page == heap_addresses.map_space_first_page) {
61    return KnownInstanceType(
62        FindKnownMapInstanceTypeInMapSpace(offset_in_page));
63  }
64  if (containing_page == heap_addresses.old_space_first_page) {
65    return KnownInstanceType(
66        FindKnownMapInstanceTypeInOldSpace(offset_in_page));
67  }
68  if (containing_page == heap_addresses.read_only_space_first_page) {
69    return KnownInstanceType(
70        FindKnownMapInstanceTypeInReadOnlySpace(offset_in_page));
71  }
72
73  // For any unknown pages, compile a list of things this object might be.
74  KnownInstanceType result;
75  if (heap_addresses.map_space_first_page == 0) {
76    int sub_result = FindKnownMapInstanceTypeInMapSpace(offset_in_page);
77    if (sub_result >= 0) {
78      result.types.push_back(static_cast<i::InstanceType>(sub_result));
79    }
80  }
81  if (heap_addresses.old_space_first_page == 0) {
82    int sub_result = FindKnownMapInstanceTypeInOldSpace(offset_in_page);
83    if (sub_result >= 0) {
84      result.types.push_back(static_cast<i::InstanceType>(sub_result));
85    }
86  }
87  if (heap_addresses.read_only_space_first_page == 0) {
88    int sub_result = FindKnownMapInstanceTypeInReadOnlySpace(offset_in_page);
89    if (sub_result >= 0) {
90      result.types.push_back(static_cast<i::InstanceType>(sub_result));
91    }
92  }
93
94  return result;
95}
96
97}  // namespace debug_helper_internal
98}  // namespace internal
99}  // namespace v8
100