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