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
12 namespace v8 {
13 namespace internal {
14
Get(Address fp)15 Handle<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
Set(Address fp,Handle<FixedArray> materialized_objects)25 void 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
Remove(Address fp)37 bool 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
StackIdToIndex(Address fp)54 int 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
GetStackEntries()61 Handle<FixedArray> MaterializedObjectStore::GetStackEntries() {
62 return Handle<FixedArray>(isolate()->heap()->materialized_objects(),
63 isolate());
64 }
65
EnsureStackEntries(int length)66 Handle<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