11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/interpreter/constant-array-builder.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <cmath>
81cb0ef41Sopenharmony_ci#include <functional>
91cb0ef41Sopenharmony_ci#include <set>
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci#include "src/ast/ast-value-factory.h"
121cb0ef41Sopenharmony_ci#include "src/ast/ast.h"
131cb0ef41Sopenharmony_ci#include "src/ast/scopes.h"
141cb0ef41Sopenharmony_ci#include "src/base/functional.h"
151cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
161cb0ef41Sopenharmony_ci#include "src/heap/local-factory-inl.h"
171cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_cinamespace v8 {
201cb0ef41Sopenharmony_cinamespace internal {
211cb0ef41Sopenharmony_cinamespace interpreter {
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ciConstantArrayBuilder::ConstantArraySlice::ConstantArraySlice(
241cb0ef41Sopenharmony_ci    Zone* zone, size_t start_index, size_t capacity, OperandSize operand_size)
251cb0ef41Sopenharmony_ci    : start_index_(start_index),
261cb0ef41Sopenharmony_ci      capacity_(capacity),
271cb0ef41Sopenharmony_ci      reserved_(0),
281cb0ef41Sopenharmony_ci      operand_size_(operand_size),
291cb0ef41Sopenharmony_ci      constants_(zone) {}
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_civoid ConstantArrayBuilder::ConstantArraySlice::Reserve() {
321cb0ef41Sopenharmony_ci  DCHECK_GT(available(), 0u);
331cb0ef41Sopenharmony_ci  reserved_++;
341cb0ef41Sopenharmony_ci  DCHECK_LE(reserved_, capacity() - constants_.size());
351cb0ef41Sopenharmony_ci}
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_civoid ConstantArrayBuilder::ConstantArraySlice::Unreserve() {
381cb0ef41Sopenharmony_ci  DCHECK_GT(reserved_, 0u);
391cb0ef41Sopenharmony_ci  reserved_--;
401cb0ef41Sopenharmony_ci}
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_cisize_t ConstantArrayBuilder::ConstantArraySlice::Allocate(
431cb0ef41Sopenharmony_ci    ConstantArrayBuilder::Entry entry, size_t count) {
441cb0ef41Sopenharmony_ci  DCHECK_GE(available(), count);
451cb0ef41Sopenharmony_ci  size_t index = constants_.size();
461cb0ef41Sopenharmony_ci  DCHECK_LT(index, capacity());
471cb0ef41Sopenharmony_ci  for (size_t i = 0; i < count; ++i) {
481cb0ef41Sopenharmony_ci    constants_.push_back(entry);
491cb0ef41Sopenharmony_ci  }
501cb0ef41Sopenharmony_ci  return index + start_index();
511cb0ef41Sopenharmony_ci}
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ciConstantArrayBuilder::Entry& ConstantArrayBuilder::ConstantArraySlice::At(
541cb0ef41Sopenharmony_ci    size_t index) {
551cb0ef41Sopenharmony_ci  DCHECK_GE(index, start_index());
561cb0ef41Sopenharmony_ci  DCHECK_LT(index, start_index() + size());
571cb0ef41Sopenharmony_ci  return constants_[index - start_index()];
581cb0ef41Sopenharmony_ci}
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ciconst ConstantArrayBuilder::Entry& ConstantArrayBuilder::ConstantArraySlice::At(
611cb0ef41Sopenharmony_ci    size_t index) const {
621cb0ef41Sopenharmony_ci  DCHECK_GE(index, start_index());
631cb0ef41Sopenharmony_ci  DCHECK_LT(index, start_index() + size());
641cb0ef41Sopenharmony_ci  return constants_[index - start_index()];
651cb0ef41Sopenharmony_ci}
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci#if DEBUG
681cb0ef41Sopenharmony_citemplate <typename IsolateT>
691cb0ef41Sopenharmony_civoid ConstantArrayBuilder::ConstantArraySlice::CheckAllElementsAreUnique(
701cb0ef41Sopenharmony_ci    IsolateT* isolate) const {
711cb0ef41Sopenharmony_ci  std::set<Smi> smis;
721cb0ef41Sopenharmony_ci  std::set<double> heap_numbers;
731cb0ef41Sopenharmony_ci  std::set<const AstRawString*> strings;
741cb0ef41Sopenharmony_ci  std::set<const char*> bigints;
751cb0ef41Sopenharmony_ci  std::set<const Scope*> scopes;
761cb0ef41Sopenharmony_ci  std::set<Object, Object::Comparer> deferred_objects;
771cb0ef41Sopenharmony_ci  for (const Entry& entry : constants_) {
781cb0ef41Sopenharmony_ci    bool duplicate = false;
791cb0ef41Sopenharmony_ci    switch (entry.tag_) {
801cb0ef41Sopenharmony_ci      case Entry::Tag::kSmi:
811cb0ef41Sopenharmony_ci        duplicate = !smis.insert(entry.smi_).second;
821cb0ef41Sopenharmony_ci        break;
831cb0ef41Sopenharmony_ci      case Entry::Tag::kHeapNumber:
841cb0ef41Sopenharmony_ci        duplicate = !heap_numbers.insert(entry.heap_number_).second;
851cb0ef41Sopenharmony_ci        break;
861cb0ef41Sopenharmony_ci      case Entry::Tag::kRawString:
871cb0ef41Sopenharmony_ci        duplicate = !strings.insert(entry.raw_string_).second;
881cb0ef41Sopenharmony_ci        break;
891cb0ef41Sopenharmony_ci      case Entry::Tag::kBigInt:
901cb0ef41Sopenharmony_ci        duplicate = !bigints.insert(entry.bigint_.c_str()).second;
911cb0ef41Sopenharmony_ci        break;
921cb0ef41Sopenharmony_ci      case Entry::Tag::kScope:
931cb0ef41Sopenharmony_ci        duplicate = !scopes.insert(entry.scope_).second;
941cb0ef41Sopenharmony_ci        break;
951cb0ef41Sopenharmony_ci      case Entry::Tag::kHandle:
961cb0ef41Sopenharmony_ci        duplicate = !deferred_objects.insert(*entry.handle_).second;
971cb0ef41Sopenharmony_ci        break;
981cb0ef41Sopenharmony_ci      case Entry::Tag::kDeferred:
991cb0ef41Sopenharmony_ci        UNREACHABLE();  // Should be kHandle at this point.
1001cb0ef41Sopenharmony_ci      case Entry::Tag::kJumpTableSmi:
1011cb0ef41Sopenharmony_ci      case Entry::Tag::kUninitializedJumpTableSmi:
1021cb0ef41Sopenharmony_ci        // TODO(leszeks): Ignore jump tables because they have to be contiguous,
1031cb0ef41Sopenharmony_ci        // so they can contain duplicates.
1041cb0ef41Sopenharmony_ci        break;
1051cb0ef41Sopenharmony_ci#define CASE_TAG(NAME, ...) case Entry::Tag::k##NAME:
1061cb0ef41Sopenharmony_ci        SINGLETON_CONSTANT_ENTRY_TYPES(CASE_TAG)
1071cb0ef41Sopenharmony_ci#undef CASE_TAG
1081cb0ef41Sopenharmony_ci        // Singletons are non-duplicated by definition.
1091cb0ef41Sopenharmony_ci        break;
1101cb0ef41Sopenharmony_ci    }
1111cb0ef41Sopenharmony_ci    if (duplicate) {
1121cb0ef41Sopenharmony_ci      std::ostringstream os;
1131cb0ef41Sopenharmony_ci      os << "Duplicate constant found: " << Brief(*entry.ToHandle(isolate))
1141cb0ef41Sopenharmony_ci         << std::endl;
1151cb0ef41Sopenharmony_ci      // Print all the entries in the slice to help debug duplicates.
1161cb0ef41Sopenharmony_ci      size_t i = start_index();
1171cb0ef41Sopenharmony_ci      for (const Entry& prev_entry : constants_) {
1181cb0ef41Sopenharmony_ci        os << i++ << ": " << Brief(*prev_entry.ToHandle(isolate)) << std::endl;
1191cb0ef41Sopenharmony_ci      }
1201cb0ef41Sopenharmony_ci      FATAL("%s", os.str().c_str());
1211cb0ef41Sopenharmony_ci    }
1221cb0ef41Sopenharmony_ci  }
1231cb0ef41Sopenharmony_ci}
1241cb0ef41Sopenharmony_ci#endif
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ciSTATIC_CONST_MEMBER_DEFINITION const size_t ConstantArrayBuilder::k8BitCapacity;
1271cb0ef41Sopenharmony_ciSTATIC_CONST_MEMBER_DEFINITION const size_t
1281cb0ef41Sopenharmony_ci    ConstantArrayBuilder::k16BitCapacity;
1291cb0ef41Sopenharmony_ciSTATIC_CONST_MEMBER_DEFINITION const size_t
1301cb0ef41Sopenharmony_ci    ConstantArrayBuilder::k32BitCapacity;
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ciConstantArrayBuilder::ConstantArrayBuilder(Zone* zone)
1331cb0ef41Sopenharmony_ci    : constants_map_(16, base::KeyEqualityMatcher<intptr_t>(),
1341cb0ef41Sopenharmony_ci                     ZoneAllocationPolicy(zone)),
1351cb0ef41Sopenharmony_ci      smi_map_(zone),
1361cb0ef41Sopenharmony_ci      smi_pairs_(zone),
1371cb0ef41Sopenharmony_ci      heap_number_map_(zone) {
1381cb0ef41Sopenharmony_ci  idx_slice_[0] =
1391cb0ef41Sopenharmony_ci      zone->New<ConstantArraySlice>(zone, 0, k8BitCapacity, OperandSize::kByte);
1401cb0ef41Sopenharmony_ci  idx_slice_[1] = zone->New<ConstantArraySlice>(
1411cb0ef41Sopenharmony_ci      zone, k8BitCapacity, k16BitCapacity, OperandSize::kShort);
1421cb0ef41Sopenharmony_ci  idx_slice_[2] = zone->New<ConstantArraySlice>(
1431cb0ef41Sopenharmony_ci      zone, k8BitCapacity + k16BitCapacity, k32BitCapacity, OperandSize::kQuad);
1441cb0ef41Sopenharmony_ci}
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_cisize_t ConstantArrayBuilder::size() const {
1471cb0ef41Sopenharmony_ci  size_t i = arraysize(idx_slice_);
1481cb0ef41Sopenharmony_ci  while (i > 0) {
1491cb0ef41Sopenharmony_ci    ConstantArraySlice* slice = idx_slice_[--i];
1501cb0ef41Sopenharmony_ci    if (slice->size() > 0) {
1511cb0ef41Sopenharmony_ci      return slice->start_index() + slice->size();
1521cb0ef41Sopenharmony_ci    }
1531cb0ef41Sopenharmony_ci  }
1541cb0ef41Sopenharmony_ci  return idx_slice_[0]->size();
1551cb0ef41Sopenharmony_ci}
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ciConstantArrayBuilder::ConstantArraySlice* ConstantArrayBuilder::IndexToSlice(
1581cb0ef41Sopenharmony_ci    size_t index) const {
1591cb0ef41Sopenharmony_ci  for (ConstantArraySlice* slice : idx_slice_) {
1601cb0ef41Sopenharmony_ci    if (index <= slice->max_index()) {
1611cb0ef41Sopenharmony_ci      return slice;
1621cb0ef41Sopenharmony_ci    }
1631cb0ef41Sopenharmony_ci  }
1641cb0ef41Sopenharmony_ci  UNREACHABLE();
1651cb0ef41Sopenharmony_ci}
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_citemplate <typename IsolateT>
1681cb0ef41Sopenharmony_ciMaybeHandle<Object> ConstantArrayBuilder::At(size_t index,
1691cb0ef41Sopenharmony_ci                                             IsolateT* isolate) const {
1701cb0ef41Sopenharmony_ci  const ConstantArraySlice* slice = IndexToSlice(index);
1711cb0ef41Sopenharmony_ci  DCHECK_LT(index, slice->capacity());
1721cb0ef41Sopenharmony_ci  if (index < slice->start_index() + slice->size()) {
1731cb0ef41Sopenharmony_ci    const Entry& entry = slice->At(index);
1741cb0ef41Sopenharmony_ci    if (!entry.IsDeferred()) return entry.ToHandle(isolate);
1751cb0ef41Sopenharmony_ci  }
1761cb0ef41Sopenharmony_ci  return MaybeHandle<Object>();
1771cb0ef41Sopenharmony_ci}
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_citemplate EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
1801cb0ef41Sopenharmony_ci    MaybeHandle<Object> ConstantArrayBuilder::At(size_t index,
1811cb0ef41Sopenharmony_ci                                                 Isolate* isolate) const;
1821cb0ef41Sopenharmony_citemplate EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
1831cb0ef41Sopenharmony_ci    MaybeHandle<Object> ConstantArrayBuilder::At(size_t index,
1841cb0ef41Sopenharmony_ci                                                 LocalIsolate* isolate) const;
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_citemplate <typename IsolateT>
1871cb0ef41Sopenharmony_ciHandle<FixedArray> ConstantArrayBuilder::ToFixedArray(IsolateT* isolate) {
1881cb0ef41Sopenharmony_ci  Handle<FixedArray> fixed_array = isolate->factory()->NewFixedArrayWithHoles(
1891cb0ef41Sopenharmony_ci      static_cast<int>(size()), AllocationType::kOld);
1901cb0ef41Sopenharmony_ci  int array_index = 0;
1911cb0ef41Sopenharmony_ci  for (const ConstantArraySlice* slice : idx_slice_) {
1921cb0ef41Sopenharmony_ci    DCHECK_EQ(slice->reserved(), 0);
1931cb0ef41Sopenharmony_ci    DCHECK(array_index == 0 ||
1941cb0ef41Sopenharmony_ci           base::bits::IsPowerOfTwo(static_cast<uint32_t>(array_index)));
1951cb0ef41Sopenharmony_ci#if DEBUG
1961cb0ef41Sopenharmony_ci    // Different slices might contain the same element due to reservations, but
1971cb0ef41Sopenharmony_ci    // all elements within a slice should be unique.
1981cb0ef41Sopenharmony_ci    slice->CheckAllElementsAreUnique(isolate);
1991cb0ef41Sopenharmony_ci#endif
2001cb0ef41Sopenharmony_ci    // Copy objects from slice into array.
2011cb0ef41Sopenharmony_ci    for (size_t i = 0; i < slice->size(); ++i) {
2021cb0ef41Sopenharmony_ci      Handle<Object> value =
2031cb0ef41Sopenharmony_ci          slice->At(slice->start_index() + i).ToHandle(isolate);
2041cb0ef41Sopenharmony_ci      fixed_array->set(array_index++, *value);
2051cb0ef41Sopenharmony_ci    }
2061cb0ef41Sopenharmony_ci    // Leave holes where reservations led to unused slots.
2071cb0ef41Sopenharmony_ci    size_t padding = slice->capacity() - slice->size();
2081cb0ef41Sopenharmony_ci    if (static_cast<size_t>(fixed_array->length() - array_index) <= padding) {
2091cb0ef41Sopenharmony_ci      break;
2101cb0ef41Sopenharmony_ci    }
2111cb0ef41Sopenharmony_ci    array_index += padding;
2121cb0ef41Sopenharmony_ci  }
2131cb0ef41Sopenharmony_ci  DCHECK_GE(array_index, fixed_array->length());
2141cb0ef41Sopenharmony_ci  return fixed_array;
2151cb0ef41Sopenharmony_ci}
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_citemplate EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
2181cb0ef41Sopenharmony_ci    Handle<FixedArray> ConstantArrayBuilder::ToFixedArray(Isolate* isolate);
2191cb0ef41Sopenharmony_citemplate EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
2201cb0ef41Sopenharmony_ci    Handle<FixedArray> ConstantArrayBuilder::ToFixedArray(
2211cb0ef41Sopenharmony_ci        LocalIsolate* isolate);
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_cisize_t ConstantArrayBuilder::Insert(Smi smi) {
2241cb0ef41Sopenharmony_ci  auto entry = smi_map_.find(smi);
2251cb0ef41Sopenharmony_ci  if (entry == smi_map_.end()) {
2261cb0ef41Sopenharmony_ci    return AllocateReservedEntry(smi);
2271cb0ef41Sopenharmony_ci  }
2281cb0ef41Sopenharmony_ci  return entry->second;
2291cb0ef41Sopenharmony_ci}
2301cb0ef41Sopenharmony_ci
2311cb0ef41Sopenharmony_cisize_t ConstantArrayBuilder::Insert(double number) {
2321cb0ef41Sopenharmony_ci  if (std::isnan(number)) return InsertNaN();
2331cb0ef41Sopenharmony_ci  auto entry = heap_number_map_.find(number);
2341cb0ef41Sopenharmony_ci  if (entry == heap_number_map_.end()) {
2351cb0ef41Sopenharmony_ci    index_t index = static_cast<index_t>(AllocateIndex(Entry(number)));
2361cb0ef41Sopenharmony_ci    heap_number_map_[number] = index;
2371cb0ef41Sopenharmony_ci    return index;
2381cb0ef41Sopenharmony_ci  }
2391cb0ef41Sopenharmony_ci  return entry->second;
2401cb0ef41Sopenharmony_ci}
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_cisize_t ConstantArrayBuilder::Insert(const AstRawString* raw_string) {
2431cb0ef41Sopenharmony_ci  return constants_map_
2441cb0ef41Sopenharmony_ci      .LookupOrInsert(reinterpret_cast<intptr_t>(raw_string),
2451cb0ef41Sopenharmony_ci                      raw_string->Hash(),
2461cb0ef41Sopenharmony_ci                      [&]() { return AllocateIndex(Entry(raw_string)); })
2471cb0ef41Sopenharmony_ci      ->value;
2481cb0ef41Sopenharmony_ci}
2491cb0ef41Sopenharmony_ci
2501cb0ef41Sopenharmony_cisize_t ConstantArrayBuilder::Insert(AstBigInt bigint) {
2511cb0ef41Sopenharmony_ci  return constants_map_
2521cb0ef41Sopenharmony_ci      .LookupOrInsert(reinterpret_cast<intptr_t>(bigint.c_str()),
2531cb0ef41Sopenharmony_ci                      static_cast<uint32_t>(base::hash_value(bigint.c_str())),
2541cb0ef41Sopenharmony_ci                      [&]() { return AllocateIndex(Entry(bigint)); })
2551cb0ef41Sopenharmony_ci      ->value;
2561cb0ef41Sopenharmony_ci}
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_cisize_t ConstantArrayBuilder::Insert(const Scope* scope) {
2591cb0ef41Sopenharmony_ci  return constants_map_
2601cb0ef41Sopenharmony_ci      .LookupOrInsert(reinterpret_cast<intptr_t>(scope),
2611cb0ef41Sopenharmony_ci                      static_cast<uint32_t>(base::hash_value(scope)),
2621cb0ef41Sopenharmony_ci                      [&]() { return AllocateIndex(Entry(scope)); })
2631cb0ef41Sopenharmony_ci      ->value;
2641cb0ef41Sopenharmony_ci}
2651cb0ef41Sopenharmony_ci
2661cb0ef41Sopenharmony_ci#define INSERT_ENTRY(NAME, LOWER_NAME)              \
2671cb0ef41Sopenharmony_ci  size_t ConstantArrayBuilder::Insert##NAME() {     \
2681cb0ef41Sopenharmony_ci    if (LOWER_NAME##_ < 0) {                        \
2691cb0ef41Sopenharmony_ci      LOWER_NAME##_ = AllocateIndex(Entry::NAME()); \
2701cb0ef41Sopenharmony_ci    }                                               \
2711cb0ef41Sopenharmony_ci    return LOWER_NAME##_;                           \
2721cb0ef41Sopenharmony_ci  }
2731cb0ef41Sopenharmony_ciSINGLETON_CONSTANT_ENTRY_TYPES(INSERT_ENTRY)
2741cb0ef41Sopenharmony_ci#undef INSERT_ENTRY
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ciConstantArrayBuilder::index_t ConstantArrayBuilder::AllocateIndex(
2771cb0ef41Sopenharmony_ci    ConstantArrayBuilder::Entry entry) {
2781cb0ef41Sopenharmony_ci  return AllocateIndexArray(entry, 1);
2791cb0ef41Sopenharmony_ci}
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ciConstantArrayBuilder::index_t ConstantArrayBuilder::AllocateIndexArray(
2821cb0ef41Sopenharmony_ci    ConstantArrayBuilder::Entry entry, size_t count) {
2831cb0ef41Sopenharmony_ci  for (size_t i = 0; i < arraysize(idx_slice_); ++i) {
2841cb0ef41Sopenharmony_ci    if (idx_slice_[i]->available() >= count) {
2851cb0ef41Sopenharmony_ci      return static_cast<index_t>(idx_slice_[i]->Allocate(entry, count));
2861cb0ef41Sopenharmony_ci    }
2871cb0ef41Sopenharmony_ci  }
2881cb0ef41Sopenharmony_ci  UNREACHABLE();
2891cb0ef41Sopenharmony_ci}
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ciConstantArrayBuilder::ConstantArraySlice*
2921cb0ef41Sopenharmony_ciConstantArrayBuilder::OperandSizeToSlice(OperandSize operand_size) const {
2931cb0ef41Sopenharmony_ci  ConstantArraySlice* slice = nullptr;
2941cb0ef41Sopenharmony_ci  switch (operand_size) {
2951cb0ef41Sopenharmony_ci    case OperandSize::kNone:
2961cb0ef41Sopenharmony_ci      UNREACHABLE();
2971cb0ef41Sopenharmony_ci    case OperandSize::kByte:
2981cb0ef41Sopenharmony_ci      slice = idx_slice_[0];
2991cb0ef41Sopenharmony_ci      break;
3001cb0ef41Sopenharmony_ci    case OperandSize::kShort:
3011cb0ef41Sopenharmony_ci      slice = idx_slice_[1];
3021cb0ef41Sopenharmony_ci      break;
3031cb0ef41Sopenharmony_ci    case OperandSize::kQuad:
3041cb0ef41Sopenharmony_ci      slice = idx_slice_[2];
3051cb0ef41Sopenharmony_ci      break;
3061cb0ef41Sopenharmony_ci  }
3071cb0ef41Sopenharmony_ci  DCHECK(slice->operand_size() == operand_size);
3081cb0ef41Sopenharmony_ci  return slice;
3091cb0ef41Sopenharmony_ci}
3101cb0ef41Sopenharmony_ci
3111cb0ef41Sopenharmony_cisize_t ConstantArrayBuilder::InsertDeferred() {
3121cb0ef41Sopenharmony_ci  return AllocateIndex(Entry::Deferred());
3131cb0ef41Sopenharmony_ci}
3141cb0ef41Sopenharmony_ci
3151cb0ef41Sopenharmony_cisize_t ConstantArrayBuilder::InsertJumpTable(size_t size) {
3161cb0ef41Sopenharmony_ci  return AllocateIndexArray(Entry::UninitializedJumpTableSmi(), size);
3171cb0ef41Sopenharmony_ci}
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_civoid ConstantArrayBuilder::SetDeferredAt(size_t index, Handle<Object> object) {
3201cb0ef41Sopenharmony_ci  ConstantArraySlice* slice = IndexToSlice(index);
3211cb0ef41Sopenharmony_ci  return slice->At(index).SetDeferred(object);
3221cb0ef41Sopenharmony_ci}
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_civoid ConstantArrayBuilder::SetJumpTableSmi(size_t index, Smi smi) {
3251cb0ef41Sopenharmony_ci  ConstantArraySlice* slice = IndexToSlice(index);
3261cb0ef41Sopenharmony_ci  // Allow others to reuse these Smis, but insert using emplace to avoid
3271cb0ef41Sopenharmony_ci  // overwriting existing values in the Smi map (which may have a smaller
3281cb0ef41Sopenharmony_ci  // operand size).
3291cb0ef41Sopenharmony_ci  smi_map_.emplace(smi, static_cast<index_t>(index));
3301cb0ef41Sopenharmony_ci  return slice->At(index).SetJumpTableSmi(smi);
3311cb0ef41Sopenharmony_ci}
3321cb0ef41Sopenharmony_ci
3331cb0ef41Sopenharmony_ciOperandSize ConstantArrayBuilder::CreateReservedEntry() {
3341cb0ef41Sopenharmony_ci  for (size_t i = 0; i < arraysize(idx_slice_); ++i) {
3351cb0ef41Sopenharmony_ci    if (idx_slice_[i]->available() > 0) {
3361cb0ef41Sopenharmony_ci      idx_slice_[i]->Reserve();
3371cb0ef41Sopenharmony_ci      return idx_slice_[i]->operand_size();
3381cb0ef41Sopenharmony_ci    }
3391cb0ef41Sopenharmony_ci  }
3401cb0ef41Sopenharmony_ci  UNREACHABLE();
3411cb0ef41Sopenharmony_ci}
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ciConstantArrayBuilder::index_t ConstantArrayBuilder::AllocateReservedEntry(
3441cb0ef41Sopenharmony_ci    Smi value) {
3451cb0ef41Sopenharmony_ci  index_t index = static_cast<index_t>(AllocateIndex(Entry(value)));
3461cb0ef41Sopenharmony_ci  smi_map_[value] = index;
3471cb0ef41Sopenharmony_ci  return index;
3481cb0ef41Sopenharmony_ci}
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_cisize_t ConstantArrayBuilder::CommitReservedEntry(OperandSize operand_size,
3511cb0ef41Sopenharmony_ci                                                 Smi value) {
3521cb0ef41Sopenharmony_ci  DiscardReservedEntry(operand_size);
3531cb0ef41Sopenharmony_ci  size_t index;
3541cb0ef41Sopenharmony_ci  auto entry = smi_map_.find(value);
3551cb0ef41Sopenharmony_ci  if (entry == smi_map_.end()) {
3561cb0ef41Sopenharmony_ci    index = AllocateReservedEntry(value);
3571cb0ef41Sopenharmony_ci  } else {
3581cb0ef41Sopenharmony_ci    ConstantArraySlice* slice = OperandSizeToSlice(operand_size);
3591cb0ef41Sopenharmony_ci    index = entry->second;
3601cb0ef41Sopenharmony_ci    if (index > slice->max_index()) {
3611cb0ef41Sopenharmony_ci      // The object is already in the constant array, but may have an
3621cb0ef41Sopenharmony_ci      // index too big for the reserved operand_size. So, duplicate
3631cb0ef41Sopenharmony_ci      // entry with the smaller operand size.
3641cb0ef41Sopenharmony_ci      index = AllocateReservedEntry(value);
3651cb0ef41Sopenharmony_ci    }
3661cb0ef41Sopenharmony_ci    DCHECK_LE(index, slice->max_index());
3671cb0ef41Sopenharmony_ci  }
3681cb0ef41Sopenharmony_ci  return index;
3691cb0ef41Sopenharmony_ci}
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_civoid ConstantArrayBuilder::DiscardReservedEntry(OperandSize operand_size) {
3721cb0ef41Sopenharmony_ci  OperandSizeToSlice(operand_size)->Unreserve();
3731cb0ef41Sopenharmony_ci}
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_citemplate <typename IsolateT>
3761cb0ef41Sopenharmony_ciHandle<Object> ConstantArrayBuilder::Entry::ToHandle(IsolateT* isolate) const {
3771cb0ef41Sopenharmony_ci  switch (tag_) {
3781cb0ef41Sopenharmony_ci    case Tag::kDeferred:
3791cb0ef41Sopenharmony_ci      // We shouldn't have any deferred entries by now.
3801cb0ef41Sopenharmony_ci      UNREACHABLE();
3811cb0ef41Sopenharmony_ci    case Tag::kHandle:
3821cb0ef41Sopenharmony_ci      return handle_;
3831cb0ef41Sopenharmony_ci    case Tag::kSmi:
3841cb0ef41Sopenharmony_ci    case Tag::kJumpTableSmi:
3851cb0ef41Sopenharmony_ci      return handle(smi_, isolate);
3861cb0ef41Sopenharmony_ci    case Tag::kUninitializedJumpTableSmi:
3871cb0ef41Sopenharmony_ci      // TODO(leszeks): There's probably a better value we could use here.
3881cb0ef41Sopenharmony_ci      return isolate->factory()->the_hole_value();
3891cb0ef41Sopenharmony_ci    case Tag::kRawString:
3901cb0ef41Sopenharmony_ci      return raw_string_->string();
3911cb0ef41Sopenharmony_ci    case Tag::kHeapNumber:
3921cb0ef41Sopenharmony_ci      return isolate->factory()->template NewNumber<AllocationType::kOld>(
3931cb0ef41Sopenharmony_ci          heap_number_);
3941cb0ef41Sopenharmony_ci    case Tag::kBigInt:
3951cb0ef41Sopenharmony_ci      // This should never fail: the parser will never create a BigInt
3961cb0ef41Sopenharmony_ci      // literal that cannot be allocated.
3971cb0ef41Sopenharmony_ci      return BigIntLiteral(isolate, bigint_.c_str()).ToHandleChecked();
3981cb0ef41Sopenharmony_ci    case Tag::kScope:
3991cb0ef41Sopenharmony_ci      return scope_->scope_info();
4001cb0ef41Sopenharmony_ci#define ENTRY_LOOKUP(Name, name) \
4011cb0ef41Sopenharmony_ci  case Tag::k##Name:             \
4021cb0ef41Sopenharmony_ci    return isolate->factory()->name();
4031cb0ef41Sopenharmony_ci      SINGLETON_CONSTANT_ENTRY_TYPES(ENTRY_LOOKUP);
4041cb0ef41Sopenharmony_ci#undef ENTRY_LOOKUP
4051cb0ef41Sopenharmony_ci  }
4061cb0ef41Sopenharmony_ci  UNREACHABLE();
4071cb0ef41Sopenharmony_ci}
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_citemplate Handle<Object> ConstantArrayBuilder::Entry::ToHandle(
4101cb0ef41Sopenharmony_ci    Isolate* isolate) const;
4111cb0ef41Sopenharmony_citemplate Handle<Object> ConstantArrayBuilder::Entry::ToHandle(
4121cb0ef41Sopenharmony_ci    LocalIsolate* isolate) const;
4131cb0ef41Sopenharmony_ci
4141cb0ef41Sopenharmony_ci}  // namespace interpreter
4151cb0ef41Sopenharmony_ci}  // namespace internal
4161cb0ef41Sopenharmony_ci}  // namespace v8
417