%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/objects/
Upload File :
Create Path :
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/objects/template-objects.cc

// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/objects/template-objects.h"

#include "src/base/functional.h"
#include "src/execution/isolate.h"
#include "src/heap/factory.h"
#include "src/objects/js-array.h"
#include "src/objects/objects-inl.h"
#include "src/objects/property-descriptor.h"
#include "src/objects/template-objects-inl.h"

namespace v8 {
namespace internal {

namespace {
bool CachedTemplateMatches(Isolate* isolate,
                           Tagged<NativeContext> native_context,
                           Tagged<JSArray> entry, int function_literal_id,
                           int slot_id, DisallowGarbageCollection& no_gc) {
  if (native_context->is_js_array_template_literal_object_map(
          entry->map(isolate))) {
    Tagged<TemplateLiteralObject> template_object =
        TemplateLiteralObject::cast(entry);
    return template_object->function_literal_id() == function_literal_id &&
           template_object->slot_id() == slot_id;
  }

  Handle<JSArray> entry_handle(entry, isolate);
  Tagged<Smi> cached_function_literal_id =
      Smi::cast(*JSReceiver::GetDataProperty(
          isolate, entry_handle,
          isolate->factory()->template_literal_function_literal_id_symbol()));
  if (cached_function_literal_id.value() != function_literal_id) return false;

  Tagged<Smi> cached_slot_id = Smi::cast(*JSReceiver::GetDataProperty(
      isolate, entry_handle,
      isolate->factory()->template_literal_slot_id_symbol()));
  if (cached_slot_id.value() != slot_id) return false;

  return true;
}
}  // namespace

// static
Handle<JSArray> TemplateObjectDescription::GetTemplateObject(
    Isolate* isolate, Handle<NativeContext> native_context,
    Handle<TemplateObjectDescription> description,
    Handle<SharedFunctionInfo> shared_info, int slot_id) {
  int function_literal_id = shared_info->function_literal_id();

  // Check the template weakmap to see if the template object already exists.
  Handle<Script> script(Script::cast(shared_info->script(isolate)), isolate);
  int32_t hash =
      EphemeronHashTable::ShapeT::Hash(ReadOnlyRoots(isolate), script);
  MaybeHandle<ArrayList> maybe_cached_templates;

  if (!IsUndefined(native_context->template_weakmap(), isolate)) {
    DisallowGarbageCollection no_gc;
    // The no_gc keeps this safe, and gcmole is confused because
    // CachedTemplateMatches calls JSReceiver::GetDataProperty.
    DisableGCMole no_gcmole;
    ReadOnlyRoots roots(isolate);
    Tagged<EphemeronHashTable> template_weakmap =
        EphemeronHashTable::cast(native_context->template_weakmap());
    Tagged<Object> cached_templates_lookup =
        template_weakmap->Lookup(isolate, script, hash);
    if (!IsTheHole(cached_templates_lookup, roots)) {
      Tagged<ArrayList> cached_templates =
          ArrayList::cast(cached_templates_lookup);
      maybe_cached_templates = handle(cached_templates, isolate);

      // Linear search over the cached template array list for a template
      // object matching the given function_literal_id + slot_id.
      // TODO(leszeks): Consider keeping this list sorted for faster lookup.
      for (int i = 0; i < cached_templates->Length(); i++) {
        Tagged<JSArray> template_object =
            JSArray::cast(cached_templates->Get(i));
        if (CachedTemplateMatches(isolate, *native_context, template_object,
                                  function_literal_id, slot_id, no_gc)) {
          return handle(template_object, isolate);
        }
      }
    }
  }

  // Create the raw object from the {raw_strings}.
  Handle<FixedArray> raw_strings(description->raw_strings(), isolate);
  Handle<FixedArray> cooked_strings(description->cooked_strings(), isolate);
  Handle<JSArray> template_object =
      isolate->factory()->NewJSArrayForTemplateLiteralArray(
          cooked_strings, raw_strings, function_literal_id, slot_id);

  // Insert the template object into the cached template array list.
  Handle<ArrayList> cached_templates;
  if (!maybe_cached_templates.ToHandle(&cached_templates)) {
    cached_templates = isolate->factory()->NewArrayList(1);
  }
  cached_templates = ArrayList::Add(isolate, cached_templates, template_object);

  // Compare the cached_templates to the original maybe_cached_templates loaded
  // from the weakmap -- if it doesn't match, we need to update the weakmap.
  Handle<ArrayList> old_cached_templates;
  if (!maybe_cached_templates.ToHandle(&old_cached_templates) ||
      *old_cached_templates != *cached_templates) {
    Tagged<HeapObject> maybe_template_weakmap =
        native_context->template_weakmap();
    Handle<EphemeronHashTable> template_weakmap;
    if (IsUndefined(maybe_template_weakmap)) {
      template_weakmap = EphemeronHashTable::New(isolate, 1);
    } else {
      template_weakmap =
          handle(EphemeronHashTable::cast(maybe_template_weakmap), isolate);
    }
    template_weakmap = EphemeronHashTable::Put(isolate, template_weakmap,
                                               script, cached_templates, hash);
    native_context->set_template_weakmap(*template_weakmap);
  }

  // Check that the list is in the appropriate location on the weakmap, and
  // that the appropriate entry is in the right location in this list.
  DCHECK_EQ(EphemeronHashTable::cast(native_context->template_weakmap())
                ->Lookup(isolate, script, hash),
            *cached_templates);
  DCHECK_EQ(cached_templates->Get(cached_templates->Length() - 1),
            *template_object);

  return template_object;
}

}  // namespace internal
}  // namespace v8

Zerion Mini Shell 1.0