Line data Source code
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 :
5 : #include "src/objects/template-objects.h"
6 :
7 : #include "src/base/functional.h"
8 : #include "src/heap/factory.h"
9 : #include "src/isolate.h"
10 : #include "src/objects-inl.h"
11 : #include "src/objects/template-objects-inl.h"
12 : #include "src/property-descriptor.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : // static
18 2774 : Handle<JSArray> TemplateObjectDescription::GetTemplateObject(
19 : Isolate* isolate, Handle<Context> native_context,
20 : Handle<TemplateObjectDescription> description,
21 : Handle<SharedFunctionInfo> shared_info, int slot_id) {
22 : DCHECK(native_context->IsNativeContext());
23 :
24 : // Check the template weakmap to see if the template object already exists.
25 : Handle<EphemeronHashTable> template_weakmap =
26 5548 : native_context->template_weakmap()->IsUndefined(isolate)
27 : ? EphemeronHashTable::New(isolate, 0)
28 5486 : : handle(EphemeronHashTable::cast(native_context->template_weakmap()),
29 2774 : isolate);
30 :
31 2774 : uint32_t hash = shared_info->Hash();
32 5548 : Object maybe_cached_template = template_weakmap->Lookup(shared_info, hash);
33 123720 : while (!maybe_cached_template->IsTheHole()) {
34 : CachedTemplateObject cached_template =
35 : CachedTemplateObject::cast(maybe_cached_template);
36 60481 : if (cached_template->slot_id() == slot_id)
37 : return handle(cached_template->template_object(), isolate);
38 :
39 : maybe_cached_template = cached_template->next();
40 : }
41 :
42 : // Create the raw object from the {raw_strings}.
43 : Handle<FixedArray> raw_strings(description->raw_strings(), isolate);
44 : Handle<JSArray> raw_object = isolate->factory()->NewJSArrayWithElements(
45 : raw_strings, PACKED_ELEMENTS, raw_strings->length(),
46 2766 : AllocationType::kOld);
47 :
48 : // Create the template object from the {cooked_strings}.
49 : Handle<FixedArray> cooked_strings(description->cooked_strings(), isolate);
50 : Handle<JSArray> template_object = isolate->factory()->NewJSArrayWithElements(
51 : cooked_strings, PACKED_ELEMENTS, cooked_strings->length(),
52 2766 : AllocationType::kOld);
53 :
54 : // Freeze the {raw_object}.
55 5532 : JSObject::SetIntegrityLevel(raw_object, FROZEN, kThrowOnError).ToChecked();
56 :
57 : // Install a "raw" data property for {raw_object} on {template_object}.
58 : PropertyDescriptor raw_desc;
59 : raw_desc.set_value(raw_object);
60 : raw_desc.set_configurable(false);
61 : raw_desc.set_enumerable(false);
62 : raw_desc.set_writable(false);
63 5532 : JSArray::DefineOwnProperty(isolate, template_object,
64 : isolate->factory()->raw_string(), &raw_desc,
65 2766 : Just(kThrowOnError))
66 : .ToChecked();
67 :
68 : // Freeze the {template_object} as well.
69 5532 : JSObject::SetIntegrityLevel(template_object, FROZEN, kThrowOnError)
70 : .ToChecked();
71 :
72 : // Insert the template object into the template weakmap.
73 : Handle<HeapObject> previous_cached_templates = handle(
74 5532 : HeapObject::cast(template_weakmap->Lookup(shared_info, hash)), isolate);
75 : Handle<CachedTemplateObject> cached_template = CachedTemplateObject::New(
76 2766 : isolate, slot_id, template_object, previous_cached_templates);
77 : template_weakmap = EphemeronHashTable::Put(
78 2766 : isolate, template_weakmap, shared_info, cached_template, hash);
79 5532 : native_context->set_template_weakmap(*template_weakmap);
80 :
81 2766 : return template_object;
82 : }
83 :
84 2766 : Handle<CachedTemplateObject> CachedTemplateObject::New(
85 : Isolate* isolate, int slot_id, Handle<JSArray> template_object,
86 : Handle<HeapObject> next) {
87 : DCHECK(next->IsCachedTemplateObject() || next->IsTheHole());
88 : Factory* factory = isolate->factory();
89 : Handle<CachedTemplateObject> result = Handle<CachedTemplateObject>::cast(
90 2766 : factory->NewStruct(TUPLE3_TYPE, AllocationType::kOld));
91 : result->set_slot_id(slot_id);
92 2766 : result->set_template_object(*template_object);
93 2766 : result->set_next(*next);
94 2766 : return result;
95 : }
96 :
97 : } // namespace internal
98 120216 : } // namespace v8
|