v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
template-objects.cc
Go to the documentation of this file.
1// Copyright 2017 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
7#include "src/base/hashing.h"
9#include "src/heap/factory.h"
14
15namespace v8 {
16namespace internal {
17
18namespace {
19bool CachedTemplateMatches(Isolate* isolate,
21 Tagged<JSArray> entry, int function_literal_id,
22 int slot_id, DisallowGarbageCollection& no_gc) {
23 if (native_context->is_js_array_template_literal_object_map(
24 entry->map(isolate))) {
25 Tagged<TemplateLiteralObject> template_object =
27 return template_object->function_literal_id() == function_literal_id &&
28 template_object->slot_id() == slot_id;
29 }
30
31 DirectHandle<JSArray> entry_handle(entry, isolate);
32 Tagged<Smi> cached_function_literal_id =
34 isolate, entry_handle,
35 isolate->factory()->template_literal_function_literal_id_symbol()));
36 if (cached_function_literal_id.value() != function_literal_id) return false;
37
39 isolate, entry_handle,
40 isolate->factory()->template_literal_slot_id_symbol()));
41 if (cached_slot_id.value() != slot_id) return false;
42
43 return true;
44}
45} // namespace
46
47// static
51 DirectHandle<SharedFunctionInfo> shared_info, int slot_id) {
52 int function_literal_id = shared_info->function_literal_id();
53
54 // Check the template weakmap to see if the template object already exists.
55 DirectHandle<Script> script(Cast<Script>(shared_info->script(isolate)),
56 isolate);
57 int32_t hash =
58 EphemeronHashTable::TodoShape::Hash(ReadOnlyRoots(isolate), script);
59 MaybeDirectHandle<ArrayList> maybe_cached_templates;
60
61 if (!IsUndefined(native_context->template_weakmap(), isolate)) {
63 // The no_gc keeps this safe, and gcmole is confused because
64 // CachedTemplateMatches calls JSReceiver::GetDataProperty.
65 DisableGCMole no_gcmole;
66 ReadOnlyRoots roots(isolate);
67 Tagged<EphemeronHashTable> template_weakmap =
68 Cast<EphemeronHashTable>(native_context->template_weakmap());
69 Tagged<Object> cached_templates_lookup =
70 template_weakmap->Lookup(isolate, script, hash);
71 if (!IsTheHole(cached_templates_lookup, roots)) {
72 Tagged<ArrayList> cached_templates =
73 Cast<ArrayList>(cached_templates_lookup);
74 maybe_cached_templates = direct_handle(cached_templates, isolate);
75
76 // Linear search over the cached template array list for a template
77 // object matching the given function_literal_id + slot_id.
78 // TODO(leszeks): Consider keeping this list sorted for faster lookup.
79 for (int i = 0; i < cached_templates->length(); i++) {
80 Tagged<JSArray> template_object =
81 Cast<JSArray>(cached_templates->get(i));
82 if (CachedTemplateMatches(isolate, *native_context, template_object,
83 function_literal_id, slot_id, no_gc)) {
84 return direct_handle(template_object, isolate);
85 }
86 }
87 }
88 }
89
90 // Create the raw object from the {raw_strings}.
91 DirectHandle<FixedArray> raw_strings(description->raw_strings(), isolate);
92 DirectHandle<FixedArray> cooked_strings(description->cooked_strings(),
93 isolate);
94 DirectHandle<JSArray> template_object =
95 isolate->factory()->NewJSArrayForTemplateLiteralArray(
96 cooked_strings, raw_strings, function_literal_id, slot_id);
97
98 // Insert the template object into the cached template array list.
99 DirectHandle<ArrayList> cached_templates;
100 if (!maybe_cached_templates.ToHandle(&cached_templates)) {
101 cached_templates = isolate->factory()->NewArrayList(1);
102 }
103 cached_templates = ArrayList::Add(isolate, cached_templates, template_object);
104
105 // Compare the cached_templates to the original maybe_cached_templates loaded
106 // from the weakmap -- if it doesn't match, we need to update the weakmap.
107 DirectHandle<ArrayList> old_cached_templates;
108 if (!maybe_cached_templates.ToHandle(&old_cached_templates) ||
109 *old_cached_templates != *cached_templates) {
110 Tagged<HeapObject> maybe_template_weakmap =
111 native_context->template_weakmap();
112 Handle<EphemeronHashTable> template_weakmap;
113 if (IsUndefined(maybe_template_weakmap)) {
114 template_weakmap = EphemeronHashTable::New(isolate, 1);
115 } else {
116 template_weakmap =
117 handle(Cast<EphemeronHashTable>(maybe_template_weakmap), isolate);
118 }
119 template_weakmap = EphemeronHashTable::Put(isolate, template_weakmap,
120 script, cached_templates, hash);
121 native_context->set_template_weakmap(*template_weakmap);
122 }
123
124 // Check that the list is in the appropriate location on the weakmap, and
125 // that the appropriate entry is in the right location in this list.
127 ->Lookup(isolate, script, hash),
128 *cached_templates);
129 DCHECK_EQ(cached_templates->get(cached_templates->length() - 1),
130 *template_object);
131
132 return template_object;
133}
134
135} // namespace internal
136} // namespace v8
static V8_EXPORT_PRIVATE DirectHandle< ArrayList > Add(Isolate *isolate, DirectHandle< ArrayList > array, Tagged< Smi > obj, AllocationType allocation=AllocationType::kYoung)
static Handle< Object > GetDataProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > name)
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
static DirectHandle< JSArray > GetTemplateObject(Isolate *isolate, DirectHandle< NativeContext > native_context, DirectHandle< TemplateObjectDescription > description, DirectHandle< SharedFunctionInfo > shared_info, int slot_id)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
Tagged(T object) -> Tagged< T >
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
!IsContextMap !IsContextMap Tagged< NativeContext >
Definition map-inl.h:877
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
#define DCHECK_EQ(v1, v2)
Definition logging.h:485