v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
constants-table-builder.cc
Go to the documentation of this file.
1// Copyright 2018 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
6
8#include "src/heap/heap-inl.h"
11#include "src/roots/roots-inl.h"
12
13namespace v8 {
14namespace internal {
15
17 : isolate_(isolate), map_(isolate->heap()) {
18 // Ensure this is only called once per Isolate.
19 DCHECK_EQ(ReadOnlyRoots(isolate_).empty_fixed_array(),
20 isolate_->heap()->builtins_constants_table());
21
22 // And that the initial value of the builtins constants table can be treated
23 // as a constant, which means that codegen will load it using the root
24 // register.
25 DCHECK(RootsTable::IsImmortalImmovable(RootIndex::kEmptyFixedArray));
26}
27
29#ifdef DEBUG
30 // Roots must not be inserted into the constants table as they are already
31 // accessibly from the root list.
32 RootIndex root_list_index;
33 DCHECK(!isolate_->roots_table().IsRootHandle(object, &root_list_index));
34 DCHECK_IMPLIES(IsMap(*object),
36
37 // Not yet finalized.
38 DCHECK_EQ(ReadOnlyRoots(isolate_).empty_fixed_array(),
39 isolate_->heap()->builtins_constants_table());
40
41 // Must be generating embedded builtin code.
43
44 // All code objects should be loaded through the root register or use
45 // pc-relative addressing.
46 DCHECK(!IsInstructionStream(*object));
47#endif
48
49 // This method is called concurrently from both the main thread and
50 // compilation threads. Constant indices need to be reproducible during
51 // builtin generation, so the main thread pre-adds all the constants. A lock
52 // is still needed since the map data structure is still being concurrently
53 // accessed.
56 auto find_result = map_.Find(object);
57 DCHECK_NOT_NULL(find_result);
58 return *find_result;
59 } else {
60 auto find_result = map_.FindOrInsert(object);
61 if (!find_result.already_exists) {
62 DCHECK(IsHeapObject(*object));
63 *find_result.entry = map_.size() - 1;
64 }
65 return *find_result.entry;
66 }
67}
68
69namespace {
70void CheckPreconditionsForPatching(Isolate* isolate,
71 Handle<Object> replacement_object) {
72 // Roots must not be inserted into the constants table as they are already
73 // accessible from the root list.
74 RootIndex root_list_index;
75 DCHECK(!isolate->roots_table().IsRootHandle(replacement_object,
76 &root_list_index));
77 USE(root_list_index);
78
79 // Not yet finalized.
80 DCHECK_EQ(ReadOnlyRoots(isolate).empty_fixed_array(),
81 isolate->heap()->builtins_constants_table());
82
83 DCHECK(isolate->IsGeneratingEmbeddedBuiltins());
84}
85} // namespace
86
88 DirectHandle<Object> self_reference,
89 Handle<InstructionStream> code_object) {
90 CheckPreconditionsForPatching(isolate_, code_object);
91 DCHECK_EQ(*self_reference, ReadOnlyRoots(isolate_).self_reference_marker());
92
93 uint32_t key;
94 if (map_.Delete(self_reference, &key)) {
95 DCHECK(IsInstructionStream(*code_object));
96 map_.Insert(code_object, key);
97 }
98}
99
101 Handle<ByteArray> counters) {
102 CheckPreconditionsForPatching(isolate_, counters);
103
104 uint32_t key;
105 if (map_.Delete(ReadOnlyRoots(isolate_).basic_block_counters_marker(),
106 &key)) {
107 map_.Insert(counters, key);
108 }
109}
110
112 HandleScope handle_scope(isolate_);
113
114 DCHECK_EQ(ReadOnlyRoots(isolate_).empty_fixed_array(),
115 isolate_->heap()->builtins_constants_table());
117
118 // An empty map means there's nothing to do.
119 if (map_.empty()) return;
120
123
124 Builtins* builtins = isolate_->builtins();
125 ConstantsMap::IteratableScope it_scope(&map_);
126 for (auto it = it_scope.begin(); it != it_scope.end(); ++it) {
127 uint32_t index = *it.entry();
128 Tagged<Object> value = it.key();
129 if (IsCode(value) && Cast<Code>(value)->kind() == CodeKind::BUILTIN) {
130 // Replace placeholder code objects with the real builtin.
131 // See also: SetupIsolateDelegate::PopulateWithPlaceholders.
132 // TODO(jgruber): Deduplicate placeholders and their corresponding
133 // builtin.
134 value = builtins->code(Cast<Code>(value)->builtin_id());
135 }
136 DCHECK(IsHeapObject(value));
137 table->set(index, value);
138 }
139
140#ifdef DEBUG
141 for (int i = 0; i < map_.size(); i++) {
142 DCHECK(IsHeapObject(table->get(i)));
143 DCHECK_NE(ReadOnlyRoots(isolate_).undefined_value(), table->get(i));
144 DCHECK_NE(ReadOnlyRoots(isolate_).self_reference_marker(), table->get(i));
145 DCHECK_NE(ReadOnlyRoots(isolate_).basic_block_counters_marker(),
146 table->get(i));
147 }
148#endif
149
151}
152
153} // namespace internal
154} // namespace v8
Isolate * isolate_
Builtins::Kind kind
Definition builtins.cc:40
void PatchBasicBlockCountersReference(Handle< ByteArray > counters)
void PatchSelfReference(DirectHandle< Object > self_reference, Handle< InstructionStream > code_object)
Handle< FixedArray > NewFixedArray(int length, AllocationType allocation=AllocationType::kYoung)
static V8_INLINE bool InReadOnlySpace(Tagged< HeapObject > object)
void SetBuiltinsConstantsTable(Tagged< FixedArray > cache)
Definition heap.cc:6828
void Insert(DirectHandle< Object > key, V v)
bool Delete(DirectHandle< Object > key, V *deleted_value)
V * Find(DirectHandle< Object > key) const
IdentityMapFindResult< V > FindOrInsert(DirectHandle< Object > key)
ThreadId thread_id() const
Definition isolate.h:821
Builtins * builtins()
Definition isolate.h:1443
v8::internal::Factory * factory()
Definition isolate.h:1527
RootsTable & roots_table()
Definition isolate.h:1250
bool IsGeneratingEmbeddedBuiltins() const
Definition isolate.h:1897
bool IsRootHandle(IndirectHandle< T > handle, RootIndex *index) const
Definition roots-inl.h:65
static constexpr bool IsImmortalImmovable(RootIndex root_index)
Definition roots.h:616
static ThreadId Current()
Definition thread-id.h:32
const MapRef map_
V8_INLINE constexpr bool IsHeapObject(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:669
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define USE(...)
Definition macros.h:293