v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
compilation-cache-table.cc
Go to the documentation of this file.
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
6
10
11namespace v8 {
12namespace internal {
13
14namespace {
15
16const int kLiteralEntryLength = 2;
17const int kLiteralInitialLength = 2;
18const int kLiteralContextOffset = 0;
19const int kLiteralLiteralsOffset = 1;
20
21int SearchLiteralsMapEntry(Tagged<CompilationCacheTable> cache,
22 InternalIndex cache_entry,
25 DCHECK(IsNativeContext(native_context));
26 Tagged<Object> obj = cache->EvalFeedbackValueAt(cache_entry);
27
28 // Check that there's no confusion between FixedArray and WeakFixedArray (the
29 // object used to be a FixedArray here).
30 DCHECK(!IsFixedArray(obj));
31 if (IsWeakFixedArray(obj)) {
33 int length = literals_map->length();
34 for (int i = 0; i < length; i += kLiteralEntryLength) {
35 DCHECK(literals_map->get(i + kLiteralContextOffset).IsWeakOrCleared());
36 if (literals_map->get(i + kLiteralContextOffset) ==
38 return i;
39 }
40 }
41 }
42 return -1;
43}
44
45void AddToFeedbackCellsMap(DirectHandle<CompilationCacheTable> cache,
46 InternalIndex cache_entry,
47 DirectHandle<Context> native_context,
48 DirectHandle<FeedbackCell> feedback_cell) {
49 Isolate* isolate = native_context->GetIsolate();
50 DCHECK(IsNativeContext(*native_context));
51 static_assert(kLiteralEntryLength == 2);
52 DirectHandle<WeakFixedArray> new_literals_map;
53 int entry;
54
55 Tagged<Object> obj = cache->EvalFeedbackValueAt(cache_entry);
56
57 // Check that there's no confusion between FixedArray and WeakFixedArray (the
58 // object used to be a FixedArray here).
59 DCHECK(!IsFixedArray(obj));
60 if (!IsWeakFixedArray(obj) || Cast<WeakFixedArray>(obj)->length() == 0) {
61 new_literals_map = isolate->factory()->NewWeakFixedArray(
62 kLiteralInitialLength, AllocationType::kOld);
63 entry = 0;
64 } else {
65 DirectHandle<WeakFixedArray> old_literals_map(Cast<WeakFixedArray>(obj),
66 isolate);
67 entry = SearchLiteralsMapEntry(*cache, cache_entry, *native_context);
68 if (entry >= 0) {
69 // Just set the code of the entry.
70 old_literals_map->set(entry + kLiteralLiteralsOffset,
71 MakeWeak(*feedback_cell));
72 return;
73 }
74
75 // Can we reuse an entry?
76 DCHECK_LT(entry, 0);
77 int length = old_literals_map->length();
78 for (int i = 0; i < length; i += kLiteralEntryLength) {
79 if (old_literals_map->get(i + kLiteralContextOffset).IsCleared()) {
80 new_literals_map = old_literals_map;
81 entry = i;
82 break;
83 }
84 }
85
86 if (entry < 0) {
87 // Copy old optimized code map and append one new entry.
88 new_literals_map = isolate->factory()->CopyWeakFixedArrayAndGrow(
89 old_literals_map, kLiteralEntryLength);
90 entry = old_literals_map->length();
91 }
92 }
93
94 new_literals_map->set(entry + kLiteralContextOffset,
96 new_literals_map->set(entry + kLiteralLiteralsOffset,
97 MakeWeak(*feedback_cell));
98
99#ifdef DEBUG
100 for (int i = 0; i < new_literals_map->length(); i += kLiteralEntryLength) {
101 Tagged<MaybeObject> object =
102 new_literals_map->get(i + kLiteralContextOffset);
103 DCHECK(object.IsCleared() ||
104 IsNativeContext(object.GetHeapObjectAssumeWeak()));
105 object = new_literals_map->get(i + kLiteralLiteralsOffset);
106 DCHECK(object.IsCleared() ||
107 IsFeedbackCell(object.GetHeapObjectAssumeWeak()));
108 }
109#endif
110
111 Tagged<Object> old_literals_map = cache->EvalFeedbackValueAt(cache_entry);
112 if (old_literals_map != *new_literals_map) {
113 cache->SetEvalFeedbackValueAt(cache_entry, *new_literals_map);
114 }
115}
116
118 InternalIndex cache_entry,
121 int entry = SearchLiteralsMapEntry(cache, cache_entry, native_context);
122 if (entry >= 0) {
123 Tagged<WeakFixedArray> literals_map =
124 Cast<WeakFixedArray>(cache->EvalFeedbackValueAt(cache_entry));
125 DCHECK_LE(entry + kLiteralEntryLength, literals_map->length());
126 Tagged<MaybeObject> object =
127 literals_map->get(entry + kLiteralLiteralsOffset);
128
129 if (!object.IsCleared()) {
130 result = Cast<FeedbackCell>(object.GetHeapObjectAssumeWeak());
131 }
132 }
133 DCHECK(result.is_null() || IsFeedbackCell(result));
134 return result;
135}
136
137// EvalCacheKeys are used as keys in the eval cache.
138class EvalCacheKey : public HashTableKey {
139 public:
140 // This tuple unambiguously identifies calls to eval() or
141 // CreateDynamicFunction() (such as through the Function() constructor).
142 // * source is the string passed into eval(). For dynamic functions, this is
143 // the effective source for the function, some of which is implicitly
144 // generated.
145 // * shared is the shared function info for the function containing the call
146 // to eval(). for dynamic functions, shared is the native context closure.
147 // * When positive, position is the position in the source where eval is
148 // called. When negative, position is the negation of the position in the
149 // dynamic function's effective source where the ')' ends the parameters.
150 EvalCacheKey(DirectHandle<String> source,
151 DirectHandle<SharedFunctionInfo> shared,
152 LanguageMode language_mode, int position)
153 : HashTableKey(CompilationCacheShape::EvalHash(*source, *shared,
154 language_mode, position)),
155 source_(source),
156 shared_(shared),
157 language_mode_(language_mode),
159
160 bool IsMatch(Tagged<Object> other) override {
162 if (!IsFixedArray(other)) {
163 DCHECK(IsNumber(other));
164 uint32_t other_hash = static_cast<uint32_t>(Object::NumberValue(other));
165 return Hash() == other_hash;
166 }
167 Tagged<FixedArray> other_array = Cast<FixedArray>(other);
168 DCHECK(IsSharedFunctionInfo(other_array->get(0)));
169 if (*shared_ != other_array->get(0)) return false;
170 int language_unchecked = Smi::ToInt(other_array->get(2));
171 DCHECK(is_valid_language_mode(language_unchecked));
172 LanguageMode language_mode = static_cast<LanguageMode>(language_unchecked);
173 if (language_mode != language_mode_) return false;
174 int position = Smi::ToInt(other_array->get(3));
175 if (position != position_) return false;
176 Tagged<String> source = Cast<String>(other_array->get(1));
177 return source->Equals(*source_);
178 }
179
180 DirectHandle<Object> AsHandle(Isolate* isolate) {
181 DirectHandle<FixedArray> array = isolate->factory()->NewFixedArray(4);
182 array->set(0, *shared_);
183 array->set(1, *source_);
184 array->set(2, Smi::FromEnum(language_mode_));
185 array->set(3, Smi::FromInt(position_));
186 array->set_map(isolate, ReadOnlyRoots(isolate).fixed_cow_array_map());
187 return array;
188 }
189
190 private:
191 DirectHandle<String> source_;
192 DirectHandle<SharedFunctionInfo> shared_;
195};
196
197// RegExpKey carries the source and flags of a regular expression as key.
198class RegExpKey : public HashTableKey {
199 public:
200 RegExpKey(Isolate* isolate, DirectHandle<String> string,
201 JSRegExp::Flags flags)
202 : HashTableKey(
204 isolate_(isolate),
205 string_(string),
206 flags_(flags) {}
207
208 // Rather than storing the key in the hash table, a pointer to the
209 // stored value is stored where the key should be. IsMatch then
210 // compares the search key to the found object, rather than comparing
211 // a key to a key.
212 // TODO(pthier): Loading the data via TrustedPointerTable on every key check
213 // is not great.
214 bool IsMatch(Tagged<Object> obj) override {
215 Tagged<RegExpData> val = Cast<RegExpDataWrapper>(obj)->data(isolate_);
216 return string_->Equals(val->source()) && (flags_ == val->flags());
217 }
218
219 Isolate* isolate_;
220 DirectHandle<String> string_;
221 JSRegExp::Flags flags_;
222};
223
224// CodeKey carries the SharedFunctionInfo key associated with a
225// Code object value.
226class CodeKey : public HashTableKey {
227 public:
228 explicit CodeKey(Handle<SharedFunctionInfo> key)
229 : HashTableKey(key->Hash()), key_(key) {}
230
231 bool IsMatch(Tagged<Object> string) override { return *key_ == string; }
232
234};
235
236Tagged<Smi> ScriptHash(Tagged<String> source,
237 MaybeDirectHandle<Object> maybe_name, int line_offset,
238 int column_offset,
239 v8::ScriptOriginOptions origin_options,
240 Isolate* isolate) {
242 size_t hash = base::hash_combine(source->EnsureHash());
243 if (DirectHandle<Object> name;
244 maybe_name.ToHandle(&name) && IsString(*name, isolate)) {
245 hash =
246 base::hash_combine(hash, Cast<String>(*name)->EnsureHash(), line_offset,
247 column_offset, origin_options.Flags());
248 }
249 // The upper bits of the hash are discarded so that the value fits in a Smi.
250 return Smi::From31BitPattern(static_cast<int>(hash & (~(1u << 31))));
251}
252
253} // namespace
254
255// We only reuse a cached function for some script source code if the
256// script originates from the same place. This is to avoid issues
257// when reporting errors, etc.
260
261 // If the script name isn't set, the boilerplate script should have
262 // an undefined name to have the same origin.
264 if (!name_.ToHandle(&name)) {
265 return IsUndefined(script->name(), isolate_);
266 }
267 // Do the fast bailout checks first.
268 if (line_offset_ != script->line_offset()) return false;
269 if (column_offset_ != script->column_offset()) return false;
270 // Check that both names are strings. If not, no match.
271 if (!IsString(*name, isolate_) || !IsString(script->name(), isolate_))
272 return false;
273 // Are the origin_options same?
274 if (origin_options_.Flags() != script->origin_options().Flags()) {
275 return false;
276 }
277 // Compare the two name strings for equality.
278 if (!Cast<String>(*name)->Equals(Cast<String>(script->name()))) {
279 return false;
280 }
281
282 Handle<FixedArray> wrapped_arguments_handle;
283 if (wrapped_arguments_.ToHandle(&wrapped_arguments_handle)) {
284 if (!script->is_wrapped()) {
285 return false;
286 }
287 Tagged<FixedArray> wrapped_arguments = *wrapped_arguments_handle;
288 Tagged<FixedArray> other_wrapped_arguments = script->wrapped_arguments();
289 int length = wrapped_arguments->length();
290 if (length != other_wrapped_arguments->length()) {
291 return false;
292 }
293 for (int i = 0; i < length; i++) {
294 Tagged<Object> arg = wrapped_arguments->get(i);
295 Tagged<Object> other_arg = other_wrapped_arguments->get(i);
296 DCHECK(IsString(arg));
297 DCHECK(IsString(other_arg));
298 if (!Cast<String>(arg)->Equals(Cast<String>(other_arg))) {
299 return false;
300 }
301 }
302 } else if (script->is_wrapped()) {
303 return false;
304 }
305
306 // Don't compare host options if the script was deserialized because we didn't
307 // serialize host options (see CodeSerializer::SerializeObjectImpl())
308 if (script->deserialized() &&
309 script->host_defined_options() ==
310 ReadOnlyRoots(isolate_).empty_fixed_array()) {
311 return true;
312 }
313 // TODO(cbruni, chromium:1244145): Remove once migrated to the context
314 Handle<Object> maybe_host_defined_options;
315 if (!host_defined_options_.ToHandle(&maybe_host_defined_options)) {
316 maybe_host_defined_options = isolate_->factory()->empty_fixed_array();
317 }
318 Tagged<FixedArray> host_defined_options =
319 Cast<FixedArray>(*maybe_host_defined_options);
320 Tagged<FixedArray> script_options =
321 Cast<FixedArray>(script->host_defined_options());
322 int length = host_defined_options->length();
323 if (length != script_options->length()) return false;
324
325 for (int i = 0; i < length; i++) {
326 // host-defined options is a v8::PrimitiveArray.
327 DCHECK(IsPrimitive(host_defined_options->get(i)));
328 DCHECK(IsPrimitive(script_options->get(i)));
329 if (!Object::StrictEquals(host_defined_options->get(i),
330 script_options->get(i))) {
331 return false;
332 }
333 }
334 return true;
335}
336
338 const ScriptDetails* script_details,
339 Isolate* isolate)
340 : ScriptCacheKey(source, script_details->name_obj,
341 script_details->line_offset, script_details->column_offset,
342 script_details->origin_options,
343 script_details->host_defined_options,
344 script_details->wrapped_arguments, isolate) {}
345
347 int line_offset, int column_offset,
348 v8::ScriptOriginOptions origin_options,
349 MaybeHandle<Object> host_defined_options,
350 MaybeHandle<FixedArray> maybe_wrapped_arguments,
351 Isolate* isolate)
352 : HashTableKey(static_cast<uint32_t>(ScriptHash(*source, name, line_offset,
353 column_offset,
354 origin_options, isolate)
355 .value())),
356 source_(source),
357 name_(name),
358 line_offset_(line_offset),
359 column_offset_(column_offset),
360 origin_options_(origin_options),
361 host_defined_options_(host_defined_options),
362 wrapped_arguments_(maybe_wrapped_arguments),
363 isolate_(isolate) {
364 DCHECK(Smi::IsValid(static_cast<int>(Hash())));
365#ifdef DEBUG
366 DirectHandle<FixedArray> wrapped_arguments;
367 if (maybe_wrapped_arguments.ToHandle(&wrapped_arguments)) {
368 int length = wrapped_arguments->length();
369 for (int i = 0; i < length; i++) {
370 Tagged<Object> arg = wrapped_arguments->get(i);
371 DCHECK(IsString(arg));
372 }
373 }
374#endif
375}
376
379 DCHECK(IsWeakFixedArray(other));
380 Tagged<WeakFixedArray> other_array = Cast<WeakFixedArray>(other);
381 DCHECK_EQ(other_array->length(), kEnd);
382
383 // A hash check can quickly reject many non-matches, even though this step
384 // isn't strictly necessary.
385 uint32_t other_hash =
386 static_cast<uint32_t>(other_array->get(kHash).ToSmi().value());
387 if (other_hash != Hash()) return false;
388
389 Tagged<HeapObject> other_script_object;
390 if (!other_array->get(kWeakScript)
391 .GetHeapObjectIfWeak(&other_script_object)) {
392 return false;
393 }
394 Tagged<Script> other_script = Cast<Script>(other_script_object);
395 Tagged<String> other_source = Cast<String>(other_script->source());
396
397 return other_source->Equals(*source_) && MatchesScript(other_script);
398}
399
401 Isolate* isolate, DirectHandle<SharedFunctionInfo> shared) {
403 isolate->factory()->NewWeakFixedArray(kEnd);
404 // Any SharedFunctionInfo being stored in the script cache should have a
405 // Script.
406 DCHECK(IsScript(shared->script()));
407 array->set(kHash, Smi::FromInt(static_cast<int>(Hash())));
408 array->set(kWeakScript, MakeWeak(shared->script()));
409 return array;
410}
411
415 if (Handle<Script> script; script_.ToHandle(&script)) {
416 result.first = *script;
417 }
419 toplevel_sfi_.ToHandle(&toplevel_sfi)) {
420 result.second = *toplevel_sfi;
421 }
422 return result;
423}
424
429 if (!raw.first.is_null()) {
430 result.script_ = handle(raw.first, isolate);
431 }
432 if (!raw.second.is_null()) {
433 result.is_compiled_scope_ = raw.second->is_compiled_scope(isolate);
434 if (result.is_compiled_scope_.is_compiled()) {
435 result.toplevel_sfi_ = handle(raw.second, isolate);
436 }
437 }
438 return result;
439}
440
443 const ScriptDetails& script_details, Isolate* isolate) {
444 src = String::Flatten(isolate, src);
445 ScriptCacheKey key(src, &script_details, isolate);
446 InternalIndex entry = table->FindEntry(isolate, &key);
447 if (entry.is_not_found()) return {};
448
450 Tagged<Object> key_in_table = table->KeyAt(entry);
453 .GetHeapObjectAssumeWeak());
454
455 Tagged<Object> obj = table->PrimaryValueAt(entry);
456 Tagged<SharedFunctionInfo> toplevel_sfi;
457 if (!IsUndefined(obj, isolate)) {
458 toplevel_sfi = Cast<SharedFunctionInfo>(obj);
459 DCHECK_EQ(toplevel_sfi->script(), script);
460 }
461
463 std::make_pair(script, toplevel_sfi), isolate);
464}
465
470 int position) {
471 InfoCellPair empty_result;
472 Isolate* isolate = native_context->GetIsolate();
473 src = String::Flatten(isolate, src);
474
475 EvalCacheKey key(src, outer_info, language_mode, position);
476 InternalIndex entry = table->FindEntry(isolate, &key);
477 if (entry.is_not_found()) return empty_result;
478
479 if (!IsFixedArray(table->KeyAt(entry))) return empty_result;
480 Tagged<Object> obj = table->PrimaryValueAt(entry);
481 if (!IsSharedFunctionInfo(obj)) return empty_result;
482
483 static_assert(CompilationCacheShape::kEntrySize == 3);
484 Tagged<FeedbackCell> feedback_cell =
485 SearchLiteralsMap(*table, entry, *native_context);
486 return InfoCellPair(isolate, Cast<SharedFunctionInfo>(obj), feedback_cell);
487}
488
490 DirectHandle<String> src, JSRegExp::Flags flags) {
491 Isolate* isolate = GetIsolate();
493 RegExpKey key(isolate, src, flags);
494 InternalIndex entry = FindEntry(isolate, &key);
495 if (entry.is_not_found()) return isolate->factory()->undefined_value();
496 return DirectHandle<Object>(PrimaryValueAt(entry), isolate);
497}
498
500 Isolate* isolate, Handle<CompilationCacheTable> cache) {
501 if (cache->HasSufficientCapacityToAdd(1)) return cache;
502
503 // Before resizing, delete are any entries whose keys contain cleared weak
504 // pointers.
505 {
507 for (InternalIndex entry : cache->IterateEntries()) {
509 if (!cache->ToKey(isolate, entry, &key)) continue;
512 .IsCleared()) {
513 DCHECK(IsUndefined(cache->PrimaryValueAt(entry)));
514 cache->RemoveEntry(entry);
515 }
516 }
517 }
518
519 return EnsureCapacity(isolate, cache);
520}
521
524 MaybeHandle<FixedArray> maybe_wrapped_arguments,
526 src = String::Flatten(isolate, src);
527 DirectHandle<Script> script(Cast<Script>(value->script()), isolate);
528 MaybeHandle<Object> script_name;
529 if (IsString(script->name(), isolate)) {
530 script_name = handle(script->name(), isolate);
531 }
532 Handle<FixedArray> host_defined_options(script->host_defined_options(),
533 isolate);
534 ScriptCacheKey key(src, script_name, script->line_offset(),
535 script->column_offset(), script->origin_options(),
536 host_defined_options, maybe_wrapped_arguments, isolate);
537 DirectHandle<Object> k = key.AsHandle(isolate, value);
538
539 // Check whether there is already a matching entry. If so, we must overwrite
540 // it. This allows an entry whose value is undefined to upgrade to contain a
541 // SharedFunctionInfo.
542 InternalIndex entry = cache->FindEntry(isolate, &key);
543 bool found_existing = entry.is_found();
544 if (!found_existing) {
545 cache = EnsureScriptTableCapacity(isolate, cache);
546 entry = cache->FindInsertionEntry(isolate, key.Hash());
547 }
548 // We might be tempted to DCHECK here that the Script in the existing entry
549 // matches the Script in the new key. However, replacing an existing Script
550 // can still happen in some edge cases that aren't common enough to be worth
551 // fixing. Consider the following unlikely sequence of events:
552 // 1. BackgroundMergeTask::SetUpOnMainThread finds a script S1 in the cache.
553 // 2. DevTools is attached and clears the cache.
554 // 3. DevTools is detached; the cache is re-enabled.
555 // 4. A new instance of the script, S2, is compiled and placed into the cache.
556 // 5. The merge from step 1 finishes on the main thread, still using S1, and
557 // places S1 into the cache, replacing S2.
558 cache->SetKeyAt(entry, *k);
559 cache->SetPrimaryValueAt(entry, *value);
560 if (!found_existing) {
561 cache->ElementAdded();
562 }
563 return cache;
564}
565
571 DirectHandle<FeedbackCell> feedback_cell, int position) {
572 Isolate* isolate = native_context->GetIsolate();
573 src = String::Flatten(isolate, src);
574 EvalCacheKey key(src, outer_info, value->language_mode(), position);
575
576 // This block handles 'real' insertions, i.e. the initial dummy insert
577 // (below) has already happened earlier.
578 {
579 DirectHandle<Object> k = key.AsHandle(isolate);
580 InternalIndex entry = cache->FindEntry(isolate, &key);
581 if (entry.is_found()) {
582 cache->SetKeyAt(entry, *k);
583 if (cache->PrimaryValueAt(entry) != *value) {
584 cache->SetPrimaryValueAt(entry, *value);
585 // The SFI is changing because the code was aged. Nuke existing feedback
586 // since it can't be reused after this point.
587 cache->SetEvalFeedbackValueAt(entry,
588 ReadOnlyRoots(isolate).the_hole_value());
589 }
590 // AddToFeedbackCellsMap may allocate a new sub-array to live in the
591 // entry, but it won't change the cache array. Therefore EntryToIndex
592 // and entry remains correct.
593 AddToFeedbackCellsMap(cache, entry, native_context, feedback_cell);
594 // Add hash again even on cache hit to avoid unnecessary cache delay in
595 // case of hash collisions.
596 }
597 }
598
599 // Create a dummy entry to mark that this key has already been inserted once.
600 cache = EnsureCapacity(isolate, cache);
601 InternalIndex entry = cache->FindInsertionEntry(isolate, key.Hash());
603 isolate->factory()->NewNumber(static_cast<double>(key.Hash()));
604 cache->SetKeyAt(entry, *k);
605 cache->SetPrimaryValueAt(entry, Smi::FromInt(kHashGenerations));
606 cache->ElementAdded();
607 return cache;
608}
609
612 DirectHandle<String> src, JSRegExp::Flags flags,
614 RegExpKey key(isolate, src, flags);
615 cache = EnsureCapacity(isolate, cache);
616 InternalIndex entry = cache->FindInsertionEntry(isolate, key.Hash());
617 // We store the value in the key slot, and compare the search key
618 // to the stored value with a custom IsMatch function during lookups.
619 cache->SetKeyAt(entry, value->wrapper());
620 cache->SetPrimaryValueAt(entry, value->wrapper());
621 cache->ElementAdded();
622 return cache;
623}
624
627 for (InternalIndex entry : IterateEntries()) {
628 if (PrimaryValueAt(entry) == value) {
629 RemoveEntry(entry);
630 }
631 }
632}
633
635 int entry_index = EntryToIndex(entry);
636 Tagged<Object> the_hole_value = GetReadOnlyRoots().the_hole_value();
637 for (int i = 0; i < kEntrySize; i++) {
638 this->set(entry_index + i, the_hole_value, SKIP_WRITE_BARRIER);
639 }
640 ElementRemoved();
641
642 // This table does not shrink upon deletion. The script cache depends on that
643 // fact, because EnsureScriptTableCapacity calls RemoveEntry at a time when
644 // shrinking the table would be counterproductive.
645}
646
647} // namespace internal
648} // namespace v8
Isolate * isolate_
std::pair< Tagged< Script >, Tagged< SharedFunctionInfo > > RawObjects
static CompilationCacheScriptLookupResult FromRawObjects(RawObjects raw, Isolate *isolate)
MaybeHandle< SharedFunctionInfo > toplevel_sfi() const
static uint32_t RegExpHash(Tagged< String > string, Tagged< Smi > flags)
static InfoCellPair LookupEval(DirectHandle< CompilationCacheTable > table, DirectHandle< String > src, DirectHandle< SharedFunctionInfo > shared, DirectHandle< NativeContext > native_context, LanguageMode language_mode, int position)
Tagged< Object > PrimaryValueAt(InternalIndex entry)
DirectHandle< Object > LookupRegExp(DirectHandle< String > source, JSRegExp::Flags flags)
static NEVER_READ_ONLY_SPACE CompilationCacheScriptLookupResult LookupScript(DirectHandle< CompilationCacheTable > table, Handle< String > src, const ScriptDetails &script_details, Isolate *isolate)
static Handle< CompilationCacheTable > EnsureScriptTableCapacity(Isolate *isolate, Handle< CompilationCacheTable > cache)
static DirectHandle< CompilationCacheTable > PutRegExp(Isolate *isolate, DirectHandle< CompilationCacheTable > cache, DirectHandle< String > src, JSRegExp::Flags flags, DirectHandle< RegExpData > value)
static DirectHandle< CompilationCacheTable > PutEval(DirectHandle< CompilationCacheTable > cache, DirectHandle< String > src, DirectHandle< SharedFunctionInfo > outer_info, DirectHandle< SharedFunctionInfo > value, DirectHandle< NativeContext > native_context, DirectHandle< FeedbackCell > feedback_cell, int position)
static DirectHandle< CompilationCacheTable > PutScript(Handle< CompilationCacheTable > cache, Handle< String > src, MaybeHandle< FixedArray > maybe_wrapped_arguments, DirectHandle< SharedFunctionInfo > value, Isolate *isolate)
uint32_t Hash() const
Definition hash-table.h:336
v8::internal::Factory * factory()
Definition isolate.h:1527
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(Handle< S > *out) const
static double NumberValue(Tagged< Number > obj)
static V8_EXPORT_PRIVATE bool StrictEquals(Tagged< Object > obj, Tagged< Object > that)
Definition objects.cc:986
MaybeHandle< FixedArray > wrapped_arguments_
ScriptCacheKey(Handle< String > source, const ScriptDetails *script_details, Isolate *isolate)
DirectHandle< Object > AsHandle(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared)
bool MatchesScript(Tagged< Script > script)
bool IsMatch(Tagged< Object > other) override
static constexpr Tagged< Smi > FromEnum(E value)
Definition smi.h:58
static constexpr int ToInt(const Tagged< Object > object)
Definition smi.h:33
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
static constexpr Tagged< Smi > From31BitPattern(int value)
Definition smi.h:52
static bool constexpr IsValid(T value)
Definition smi.h:67
static V8_INLINE HandleType< String > Flatten(Isolate *isolate, HandleType< T > string, AllocationType allocation=AllocationType::kYoung)
bool GetHeapObjectIfWeak(Tagged< HeapObject > *result) const
LanguageMode language_mode_
Handle< SharedFunctionInfo > key_
JSRegExp::Flags flags_
DirectHandle< String > string_
Handle< String > source_
Definition compiler.cc:3791
const int position_
Tagged< SharedFunctionInfo > shared_
Definition debug.cc:1741
ZoneVector< RpoNumber > & result
int position
Definition liveedit.cc:290
const char * name_
V8_INLINE size_t hash_combine(size_t seed, size_t hash)
Definition hashing.h:77
bool is_valid_language_mode(int language_mode)
Definition globals.h:781
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
@ SKIP_WRITE_BARRIER
Definition objects.h:52
bool IsNumber(Tagged< Object > obj)
ReadOnlyRoots GetReadOnlyRoots()
Definition roots-inl.h:86
Tagged(T object) -> Tagged< T >
kStaticElementsTemplateOffset kInstancePropertiesTemplateOffset Tagged< FixedArray >
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
Definition flags.cc:2086
bool IsPrimitive(Tagged< Object > obj)
static uint32_t Hash(RegisteredExtension *extension)
Tagged< MaybeWeak< T > > MakeWeak(Tagged< T > value)
Definition tagged.h:893
return value
Definition map-inl.h:893
template const char * string
kInterpreterTrampolineOffset script
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
Local< T > Handle
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485