1// Copyright 2021 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 "src/deoptimizer/materialized-object-store.h"
6
7#include "src/execution/isolate.h"
8#include "src/heap/heap-inl.h"
9#include "src/objects/fixed-array-inl.h"
10#include "src/objects/oddball.h"
11
12namespace v8 {
13namespace internal {
14
15Handle<FixedArray> MaterializedObjectStore::Get(Address fp) {
16  int index = StackIdToIndex(fp);
17  if (index == -1) {
18    return Handle<FixedArray>::null();
19  }
20  Handle<FixedArray> array = GetStackEntries();
21  CHECK_GT(array->length(), index);
22  return Handle<FixedArray>::cast(Handle<Object>(array->get(index), isolate()));
23}
24
25void MaterializedObjectStore::Set(Address fp,
26                                  Handle<FixedArray> materialized_objects) {
27  int index = StackIdToIndex(fp);
28  if (index == -1) {
29    index = static_cast<int>(frame_fps_.size());
30    frame_fps_.push_back(fp);
31  }
32
33  Handle<FixedArray> array = EnsureStackEntries(index + 1);
34  array->set(index, *materialized_objects);
35}
36
37bool MaterializedObjectStore::Remove(Address fp) {
38  auto it = std::find(frame_fps_.begin(), frame_fps_.end(), fp);
39  if (it == frame_fps_.end()) return false;
40  int index = static_cast<int>(std::distance(frame_fps_.begin(), it));
41
42  frame_fps_.erase(it);
43  FixedArray array = isolate()->heap()->materialized_objects();
44
45  CHECK_LT(index, array.length());
46  int fps_size = static_cast<int>(frame_fps_.size());
47  for (int i = index; i < fps_size; i++) {
48    array.set(i, array.get(i + 1));
49  }
50  array.set(fps_size, ReadOnlyRoots(isolate()).undefined_value());
51  return true;
52}
53
54int MaterializedObjectStore::StackIdToIndex(Address fp) {
55  auto it = std::find(frame_fps_.begin(), frame_fps_.end(), fp);
56  return it == frame_fps_.end()
57             ? -1
58             : static_cast<int>(std::distance(frame_fps_.begin(), it));
59}
60
61Handle<FixedArray> MaterializedObjectStore::GetStackEntries() {
62  return Handle<FixedArray>(isolate()->heap()->materialized_objects(),
63                            isolate());
64}
65
66Handle<FixedArray> MaterializedObjectStore::EnsureStackEntries(int length) {
67  Handle<FixedArray> array = GetStackEntries();
68  if (array->length() >= length) {
69    return array;
70  }
71
72  int new_length = length > 10 ? length : 10;
73  if (new_length < 2 * array->length()) {
74    new_length = 2 * array->length();
75  }
76
77  Handle<FixedArray> new_array =
78      isolate()->factory()->NewFixedArray(new_length, AllocationType::kOld);
79  for (int i = 0; i < array->length(); i++) {
80    new_array->set(i, array->get(i));
81  }
82  HeapObject undefined_value = ReadOnlyRoots(isolate()).undefined_value();
83  for (int i = array->length(); i < length; i++) {
84    new_array->set(i, undefined_value);
85  }
86  isolate()->heap()->SetRootMaterializedObjects(*new_array);
87  return new_array;
88}
89
90}  // namespace internal
91}  // namespace v8
92