v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
factory-base.cc
Go to the documentation of this file.
1// Copyright 2020 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
8#include "src/ast/ast.h"
10#include "src/common/globals.h"
13#include "src/heap/factory.h"
14#include "src/heap/heap-inl.h"
20#include "src/logging/log.h"
26#include "src/objects/oddball.h"
31#include "src/objects/string.h"
34#include "src/roots/roots.h"
35#include "src/sandbox/check.h"
36
37namespace v8 {
38namespace internal {
39
40template <typename Impl>
41template <AllocationType allocation>
43 static_assert(sizeof(HeapNumber) <= kMaxRegularHeapObjectSize);
44 Tagged<Map> map = read_only_roots().heap_number_map();
45 Tagged<HeapObject> result = AllocateRawWithImmortalMap(
46 sizeof(HeapNumber), allocation, map, kDoubleUnaligned);
48}
49
58
61
62template <typename Impl>
64 AllocationType allocation) {
65 ReadOnlyRoots roots = read_only_roots();
66 Tagged<Map> map = Map::GetMapFor(roots, type);
67 int size = map->instance_size();
68 return handle(NewStructInternal(roots, map, size, allocation), isolate());
69}
70
71template <typename Impl>
73 auto accessors =
74 NewStructInternal<AccessorPair>(ACCESSOR_PAIR_TYPE, AllocationType::kOld);
76 accessors->set_getter(read_only_roots().null_value(), SKIP_WRITE_BARRIER);
77 accessors->set_setter(read_only_roots().null_value(), SKIP_WRITE_BARRIER);
78 return handle(accessors, isolate());
79}
80
81template <typename Impl>
83 DirectHandle<CodeWrapper> wrapper = NewCodeWrapper();
84 Tagged<Map> map = read_only_roots().code_map();
85 int size = map->instance_size();
87 AllocateRawWithImmortalMap(size, AllocationType::kTrusted, map));
89 code->init_self_indirect_pointer(isolate());
90 code->initialize_flags(options.kind, options.is_context_specialized,
91 options.is_turbofanned);
92 code->set_builtin_id(options.builtin);
93 code->set_instruction_size(options.instruction_size);
94 code->set_metadata_size(options.metadata_size);
95 code->set_inlined_bytecode_size(options.inlined_bytecode_size);
96 code->set_osr_offset(options.osr_offset);
97 SBXCHECK_IMPLIES(options.deoptimization_data.is_null(),
98 options.osr_offset.IsNone());
99 code->set_handler_table_offset(options.handler_table_offset);
100 code->set_constant_pool_offset(options.constant_pool_offset);
101 code->set_code_comments_offset(options.code_comments_offset);
102 code->set_builtin_jump_table_info_offset(
103 options.builtin_jump_table_info_offset);
104 code->set_unwinding_info_offset(options.unwinding_info_offset);
105 code->set_parameter_count(options.parameter_count);
106#ifdef V8_ENABLE_LEAPTIERING
107 code->set_js_dispatch_handle(kNullJSDispatchHandle);
108#endif // V8_ENABLE_LEAPTIERING
109
110 // Set bytecode/interpreter data or deoptimization data.
111 if (CodeKindUsesBytecodeOrInterpreterData(options.kind)) {
112 DCHECK(options.deoptimization_data.is_null());
114 *options.bytecode_or_interpreter_data.ToHandleChecked();
115 DCHECK(IsBytecodeArray(data) || IsInterpreterData(data));
116 code->set_bytecode_or_interpreter_data(data);
117 } else if (CodeKindUsesDeoptimizationData(options.kind)) {
118 DCHECK(options.bytecode_or_interpreter_data.is_null());
119 code->set_deoptimization_data(
120 *options.deoptimization_data.ToHandleChecked());
121 } else {
122 DCHECK(options.deoptimization_data.is_null());
123 DCHECK(options.bytecode_or_interpreter_data.is_null());
124 code->clear_deoptimization_data_and_interpreter_data();
125 }
126
127 // Set bytecode offset table or source position table.
128 if (CodeKindUsesBytecodeOffsetTable(options.kind)) {
129 DCHECK(options.source_position_table.is_null());
130 code->set_bytecode_offset_table(
131 *options.bytecode_offset_table.ToHandleChecked());
132 } else if (CodeKindMayLackSourcePositionTable(options.kind)) {
133 DCHECK(options.bytecode_offset_table.is_null());
135 if (options.source_position_table.ToHandle(&table)) {
136 code->set_source_position_table(*table);
137 } else {
138 code->clear_source_position_table_and_bytecode_offset_table();
140 } else {
141 DCHECK(options.bytecode_offset_table.is_null());
142 code->set_source_position_table(
143 *options.source_position_table.ToHandleChecked());
144 }
146 // Set instruction stream and entrypoint.
148 if (options.instruction_stream.ToHandle(&istream)) {
149 DCHECK_EQ(options.instruction_start, kNullAddress);
150 code->SetInstructionStreamAndInstructionStart(isolate(), *istream);
151 } else {
152 DCHECK_NE(options.instruction_start, kNullAddress);
153 code->set_raw_instruction_stream(Smi::zero(), SKIP_WRITE_BARRIER);
154 code->SetInstructionStartForOffHeapBuiltin(isolate(),
155 options.instruction_start);
157
158 wrapper->set_code(code);
159 code->set_wrapper(*wrapper);
161 code->clear_padding();
162 return handle(code, isolate());
163}
164
165template <typename Impl>
168 Cast<CodeWrapper>(NewWithImmortalMap(read_only_roots().code_wrapper_map(),
170 isolate());
171 // The CodeWrapper is typically created before the Code object it wraps, so
172 // the code field cannot yet be set. However, as a heap verifier might see
173 // the wrapper before the field can be set, we need to clear the field here.
174 wrapper->clear_code();
175 return wrapper;
176}
177
178template <typename Impl>
180 AllocationType allocation) {
181 return FixedArray::New(isolate(), length, allocation);
182}
183
184template <typename Impl>
186 int length, AllocationType allocation) {
188 allocation == AllocationType::kSharedTrusted);
189
190 // TODO(saelo): Move this check to TrustedFixedArray::New once we have a RO
191 // trusted space.
192 if (length == 0) return empty_trusted_fixed_array();
193 return TrustedFixedArray::New(isolate(), length, allocation);
194}
195
196template <typename Impl>
198 int length) {
199 if (length == 0) return empty_protected_fixed_array();
200 return ProtectedFixedArray::New(isolate(), length);
201}
202
203template <typename Impl>
205 DirectHandle<Map> map, int length, AllocationType allocation) {
206 // Zero-length case must be handled outside, where the knowledge about
207 // the map is.
208 DCHECK_LT(0, length);
209 return NewFixedArrayWithFiller(map, length, undefined_value(), allocation);
210}
212template <typename Impl>
214 int length, AllocationType allocation) {
215 DCHECK_LE(0, length);
216 if (length == 0) return impl()->empty_fixed_array();
217 return NewFixedArrayWithFiller(fixed_array_map(), length, the_hole_value(),
218 allocation);
219}
220
221template <typename Impl>
224 AllocationType allocation) {
225 Tagged<HeapObject> result = AllocateRawFixedArray(length, allocation);
229 result->set_map_after_allocation(isolate(), *map, SKIP_WRITE_BARRIER);
231 array->set_length(length);
232 MemsetTagged(array->RawFieldOfFirstElement(), *filler, length);
233 return handle(array, isolate());
234}
235
236template <typename Impl>
238 int length, AllocationType allocation) {
239 DCHECK_LE(0, length);
240 if (length == 0) return impl()->empty_fixed_array();
242 FATAL("Invalid FixedArray size %d", length);
243 }
244 Tagged<HeapObject> result = AllocateRawFixedArray(length, allocation);
246 result->set_map_after_allocation(
247 isolate(), read_only_roots().fixed_array_map(), SKIP_WRITE_BARRIER);
249 array->set_length(length);
250 MemsetTagged(array->RawFieldOfFirstElement(), Smi::zero(), length);
251 return direct_handle(array, isolate());
253
254template <typename Impl>
256 int length, AllocationType allocation) {
257 return FixedDoubleArray::New(isolate(), length, allocation);
258}
259
260template <typename Impl>
262 Tagged<Map> map, int length, AllocationType allocation) {
263 // Zero-length case must be handled outside.
264 DCHECK_LT(0, length);
268 AllocateRawArray(WeakFixedArray::SizeFor(length), allocation);
269 result->set_map_after_allocation(isolate(), map, SKIP_WRITE_BARRIER);
272 array->set_length(length);
273 MemsetTagged(ObjectSlot(array->RawFieldOfFirstElement()),
274 read_only_roots().undefined_value(), length);
275
276 return handle(array, isolate());
277}
278
279template <typename Impl>
281 int length, AllocationType allocation) {
282 return WeakFixedArray::New(isolate(), length, allocation);
283}
285template <typename Impl>
287 int length) {
288 // TODO(saelo): Move this check to TrustedWeakFixedArray::New once we have a
289 // RO trusted space.
290 if (length == 0) return empty_trusted_weak_fixed_array();
291 return TrustedWeakFixedArray::New(isolate(), length);
292}
293
294template <typename Impl>
296 int length) {
297 // TODO(saelo): Move this check to ProtectedWeakFixedArray::New once we have
298 // a RO trusted space.
299 if (length == 0) return empty_protected_weak_fixed_array();
300 return ProtectedWeakFixedArray::New(isolate(), length);
301}
303template <typename Impl>
305 AllocationType allocation) {
306 return ByteArray::New(isolate(), length, allocation);
307}
309template <typename Impl>
311 int length, AllocationType allocation_type) {
312 if (length == 0) return empty_trusted_byte_array();
313 return TrustedByteArray::New(isolate(), length, allocation_type);
314}
315
316template <typename Impl>
319 return Cast<DeoptimizationLiteralArray>(NewTrustedWeakFixedArray(length));
321
322template <typename Impl>
325 return Cast<DeoptimizationFrameTranslation>(NewTrustedByteArray(length));
326}
327
328template <typename Impl>
330 int length, const uint8_t* raw_bytecodes, int frame_size,
331 uint16_t parameter_count, uint16_t max_arguments,
333 DirectHandle<TrustedByteArray> handler_table, AllocationType allocation) {
334 DCHECK(allocation == AllocationType::kTrusted ||
335 allocation == AllocationType::kSharedTrusted);
337 FATAL("Fatal JavaScript invalid size error %d", length);
338 UNREACHABLE();
339 }
340 DirectHandle<BytecodeWrapper> wrapper = NewBytecodeWrapper();
341 int size = BytecodeArray::SizeFor(length);
342 Tagged<HeapObject> result = AllocateRawWithImmortalMap(
343 size, allocation, read_only_roots().bytecode_array_map());
346 instance->init_self_indirect_pointer(isolate());
347 instance->set_length(length);
348 instance->set_frame_size(frame_size);
349 instance->set_parameter_count(parameter_count);
350 instance->set_max_arguments(max_arguments);
351 instance->set_incoming_new_target_or_generator_register(
353 instance->set_constant_pool(*constant_pool);
354 instance->set_handler_table(*handler_table);
355 instance->clear_source_position_table(kReleaseStore);
356 instance->set_wrapper(*wrapper);
357 CopyBytes(reinterpret_cast<uint8_t*>(instance->GetFirstBytecodeAddress()),
358 raw_bytecodes, length);
359 instance->clear_padding();
360 wrapper->set_bytecode(instance);
361 return handle(instance, isolate());
363
364template <typename Impl>
366 AllocationType allocation) {
368 allocation == AllocationType::kSharedOld);
369
371 Cast<BytecodeWrapper>(NewWithImmortalMap(
372 read_only_roots().bytecode_wrapper_map(), allocation)),
373 isolate());
374 // The BytecodeWrapper is typically created before the BytecodeArray it
375 // wraps, so the bytecode field cannot yet be set. However, as a heap
376 // verifier might see the wrapper before the field can be set, we need to
377 // clear the field here.
378 wrapper->clear_bytecode();
379 return wrapper;
380}
382template <typename Impl>
385 ScriptEventType script_event_type) {
386 return NewScriptWithId(source, isolate()->GetNextScriptId(),
387 script_event_type);
388}
389
390template <typename Impl>
392 DirectHandle<UnionOf<String, Undefined>> source, int script_id,
393 ScriptEventType script_event_type) {
394 DCHECK(IsString(*source) || IsUndefined(*source));
395 // Create and initialize script object.
396 ReadOnlyRoots roots = read_only_roots();
397 Handle<Script> script = handle(
398 NewStructInternal<Script>(SCRIPT_TYPE, AllocationType::kOld), isolate());
401 Tagged<Script> raw = *script;
402 raw->set_source(*source);
403 raw->set_name(roots.undefined_value(), SKIP_WRITE_BARRIER);
404 raw->set_id(script_id);
405 raw->set_line_offset(0);
406 raw->set_column_offset(0);
407 raw->set_context_data(roots.undefined_value(), SKIP_WRITE_BARRIER);
408 raw->set_type(Script::Type::kNormal);
409 raw->set_line_ends(Smi::zero());
410 raw->set_eval_from_shared_or_wrapped_arguments(roots.undefined_value(),
412 raw->set_eval_from_position(0);
413 raw->set_infos(roots.empty_weak_fixed_array(), SKIP_WRITE_BARRIER);
414 raw->set_flags(0);
415 raw->set_host_defined_options(roots.empty_fixed_array(),
417 raw->set_source_hash(roots.undefined_value(), SKIP_WRITE_BARRIER);
418 raw->set_compiled_lazy_function_positions(roots.undefined_value(),
420#ifdef V8_SCRIPTORMODULE_LEGACY_LIFETIME
421 raw->set_script_or_modules(roots.empty_array_list());
422#endif
423 }
424 impl()->ProcessNewScript(script, script_event_type);
425 return script;
426}
427
428template <typename Impl>
431 int length, DirectHandle<Context> context,
432 DirectHandle<FixedArray> arguments, AllocationType allocation) {
434 Cast<SloppyArgumentsElements>(AllocateRawWithImmortalMap(
436 read_only_roots().sloppy_arguments_elements_map()));
437
439 WriteBarrierMode write_barrier_mode = allocation == AllocationType::kYoung
442 result->set_length(length);
443 result->set_context(*context, write_barrier_mode);
444 result->set_arguments(*arguments, write_barrier_mode);
446}
447
448template <typename Impl>
450 int size, AllocationType allocation) {
451 return ArrayList::New(isolate(), size, allocation);
452}
454template <typename Impl>
456 FunctionLiteral* literal, DirectHandle<Script> script, bool is_toplevel) {
459 NewSharedFunctionInfo(literal->GetName(isolate()), {},
460 Builtin::kCompileLazy, 0, kDontAdapt, kind);
461 shared->set_function_literal_id(literal->function_literal_id());
464 shared->SetScript(isolate(), read_only_roots(), *script,
465 literal->function_literal_id(), false);
466 return shared;
467}
468
469template <typename Impl>
472 Tagged<Map> map = read_only_roots().shared_function_info_map();
473
475 Cast<SharedFunctionInfo>(NewWithImmortalMap(map, AllocationType::kOld));
477
478 shared->clear_padding();
479 shared->CopyFrom(*other, isolate());
480
481 return handle(shared, isolate());
482}
483
484template <typename Impl>
488 Tagged<Map> map = read_only_roots().shared_function_info_wrapper_map();
490 NewWithImmortalMap(map, AllocationType::kTrusted));
491
492 wrapper->set_shared_info(*sfi);
493
494 return direct_handle(wrapper, isolate());
495}
496
497template <typename Impl>
499 int children_length) {
500 int size = PreparseData::SizeFor(data_length, children_length);
501 Tagged<PreparseData> result = Cast<PreparseData>(AllocateRawWithImmortalMap(
502 size, AllocationType::kOld, read_only_roots().preparse_data_map()));
504 result->set_data_length(data_length);
505 result->set_children_length(children_length);
506 MemsetTagged(result->inner_data_start(), read_only_roots().null_value(),
507 children_length);
508 result->clear_padding();
509 return handle(result, isolate());
510}
511
512template <typename Impl>
515 Handle<String> inferred_name, int32_t start_position,
516 int32_t end_position) {
517 return TorqueGeneratedFactory<Impl>::NewUncompiledDataWithoutPreparseData(
518 inferred_name, start_position, end_position, AllocationType::kTrusted);
519}
520
521template <typename Impl>
524 Handle<String> inferred_name, int32_t start_position, int32_t end_position,
525 Handle<PreparseData> preparse_data) {
526 return TorqueGeneratedFactory<Impl>::NewUncompiledDataWithPreparseData(
527 inferred_name, start_position, end_position, preparse_data,
529}
530
531template <typename Impl>
534 Handle<String> inferred_name, int32_t start_position,
535 int32_t end_position) {
536 return TorqueGeneratedFactory<Impl>::
537 NewUncompiledDataWithoutPreparseDataWithJob(inferred_name, start_position,
538 end_position, kNullAddress,
540}
541
542template <typename Impl>
545 Handle<String> inferred_name, int32_t start_position, int32_t end_position,
546 Handle<PreparseData> preparse_data) {
547 return TorqueGeneratedFactory<Impl>::NewUncompiledDataWithPreparseDataAndJob(
548 inferred_name, start_position, end_position, preparse_data, kNullAddress,
550}
551
552template <typename Impl>
554 MaybeDirectHandle<String> maybe_name,
555 MaybeDirectHandle<HeapObject> maybe_function_data, Builtin builtin, int len,
558 NewSharedFunctionInfo(AllocationType::kOld);
561 // Function names are assumed to be flat elsewhere.
562 DirectHandle<String> shared_name;
563 bool has_shared_name = maybe_name.ToHandle(&shared_name);
564 if (has_shared_name) {
565 DCHECK(shared_name->IsFlat());
566 raw->set_name_or_scope_info(*shared_name, kReleaseStore);
567 } else {
568 DCHECK_EQ(raw->name_or_scope_info(kAcquireLoad),
570 }
571
572 DirectHandle<HeapObject> function_data;
573 if (maybe_function_data.ToHandle(&function_data)) {
574 // If we pass function_data then we shouldn't pass a builtin index, and
575 // the function_data should not be code with a builtin.
576 DCHECK(!Builtins::IsBuiltinId(builtin));
577 DCHECK(!IsInstructionStream(*function_data));
578 DCHECK(!IsCode(*function_data));
579 if (IsExposedTrustedObject(*function_data)) {
580 raw->SetTrustedData(Cast<ExposedTrustedObject>(*function_data));
581 } else {
582 raw->SetUntrustedData(*function_data);
583 }
584 } else if (Builtins::IsBuiltinId(builtin)) {
585 raw->set_builtin_id(builtin);
586 } else {
587 DCHECK(raw->HasBuiltinId());
588 DCHECK_EQ(Builtin::kIllegal, raw->builtin_id());
589 }
590
591 raw->CalculateConstructAsBuiltin();
592 raw->set_kind(kind);
593
594 switch (adapt) {
596 raw->set_formal_parameter_count(JSParameterCount(len));
597 break;
599 raw->DontAdaptArguments();
600 break;
601 }
602 raw->set_length(len);
603
604 DCHECK_IMPLIES(raw->HasBuiltinId(),
606 raw->builtin_id(), raw->length(),
607 raw->internal_formal_parameter_count_with_receiver()));
608#ifdef VERIFY_HEAP
609 if (v8_flags.verify_heap) raw->SharedFunctionInfoVerify(isolate());
610#endif // VERIFY_HEAP
611 return shared;
612}
613
614template <typename Impl>
617 int all_properties,
618 int index_keys,
619 bool has_seen_proto) {
621 isolate(), boilerplate, all_properties, index_keys, has_seen_proto,
623}
624
625template <typename Impl>
628 ElementsKind elements_kind, DirectHandle<FixedArrayBase> constant_values) {
629 auto result = NewStructInternal<ArrayBoilerplateDescription>(
630 ARRAY_BOILERPLATE_DESCRIPTION_TYPE, AllocationType::kOld);
632 result->set_elements_kind(elements_kind);
633 result->set_constant_elements(*constant_values);
634 return handle(result, isolate());
635}
636
637template <typename Impl>
640 Cast<RegExpDataWrapper>(NewWithImmortalMap(
641 read_only_roots().regexp_data_wrapper_map(), AllocationType::kOld)),
642 isolate());
643 wrapper->clear_data();
644 return wrapper;
645}
646
647template <typename Impl>
651 Tagged<Smi> flags) {
652 auto result = NewStructInternal<RegExpBoilerplateDescription>(
653 REG_EXP_BOILERPLATE_DESCRIPTION_TYPE, AllocationType::kOld);
655 result->set_data(*data);
656 result->set_source(*source);
657 result->set_flags(flags.value());
658 return direct_handle(result, isolate());
659}
660
661template <typename Impl>
664 DirectHandle<FixedArray> raw_strings,
665 DirectHandle<FixedArray> cooked_strings) {
666 DCHECK_EQ(raw_strings->length(), cooked_strings->length());
667 DCHECK_LT(0, raw_strings->length());
668 auto result = NewStructInternal<TemplateObjectDescription>(
669 TEMPLATE_OBJECT_DESCRIPTION_TYPE, AllocationType::kOld);
671 result->set_raw_strings(*raw_strings);
672 result->set_cooked_strings(*cooked_strings);
673 return handle(result, isolate());
674}
675
676template <typename Impl>
678 int slot_count, int create_closure_slot_count, AllocationType allocation) {
679 DCHECK_LE(0, slot_count);
680 int size = FeedbackMetadata::SizeFor(slot_count, create_closure_slot_count);
682 Cast<FeedbackMetadata>(AllocateRawWithImmortalMap(
683 size, allocation, read_only_roots().feedback_metadata_map()));
684 result->set_slot_count(slot_count);
685 result->set_create_closure_slot_count(create_closure_slot_count);
686
687 // Initialize the data section to 0.
688 int data_size = size - FeedbackMetadata::kHeaderSize;
689 Address data_start = result->address() + FeedbackMetadata::kHeaderSize;
690 memset(reinterpret_cast<uint8_t*>(data_start), 0, data_size);
691 // Fields have been zeroed out but not initialized, so this object will not
692 // pass object verification at this point.
693 return handle(result, isolate());
694}
695
696template <typename Impl>
698 const ZoneVector<SourceRange>& slots) {
699 const int slot_count = static_cast<int>(slots.size());
700
701 int size = CoverageInfo::SizeFor(slot_count);
702 Tagged<Map> map = read_only_roots().coverage_info_map();
704 AllocateRawWithImmortalMap(size, AllocationType::kOld, map));
705 info->set_slot_count(slot_count);
706 for (int i = 0; i < slot_count; i++) {
707 SourceRange range = slots[i];
708 info->InitializeSlot(i, range.start, range.end);
709 }
710 return handle(info, isolate());
711}
712
713template <typename Impl>
715 uint16_t c2) {
716 if ((c1 | c2) <= unibrow::Latin1::kMaxChar) {
717 uint8_t buffer[] = {static_cast<uint8_t>(c1), static_cast<uint8_t>(c2)};
719 }
720 uint16_t buffer[] = {c1, c2};
722}
723
724template <typename Impl>
725template <class StringTableKey>
731
744
751
752template <typename Impl>
754 base::Vector<const uint8_t> string, bool convert_encoding) {
755 SequentialStringKey<uint8_t> key(string, HashSeed(read_only_roots()),
756 convert_encoding);
757 return InternalizeStringWithKey(&key);
758}
759
760template <typename Impl>
762 base::Vector<const uint16_t> string, bool convert_encoding) {
763 SequentialStringKey<uint16_t> key(string, HashSeed(read_only_roots()),
764 convert_encoding);
765 return InternalizeStringWithKey(&key);
766}
767
768template <typename Impl>
770 base::Vector<const uint8_t> str, uint32_t raw_hash_field) {
772 AllocateRawOneByteInternalizedString(str.length(), raw_hash_field);
773 // No synchronization is needed since the shared string hasn't yet escaped to
774 // script.
777 str.begin(), str.length());
778 return result;
779}
780
781template <typename Impl>
783 base::Vector<const base::uc16> str, uint32_t raw_hash_field) {
785 AllocateRawTwoByteInternalizedString(str.length(), raw_hash_field);
786 // No synchronization is needed since the shared string hasn't yet escaped to
787 // script.
790 str.begin(), str.length() * base::kUC16Size);
791 return result;
792}
793
794template <typename Impl>
797 base::Vector<const base::uc16> str, uint32_t raw_hash_field) {
799 AllocateRawOneByteInternalizedString(str.length(), raw_hash_field);
801 CopyChars(
803 str.begin(), str.length());
804 return result;
805}
806
807template <typename Impl>
808template <typename SeqStringT>
810 int length, Tagged<Map> map, AllocationType allocation) {
811 DCHECK(SeqStringT::IsCompatibleMap(map, read_only_roots()));
813 RefineAllocationTypeForInPlaceInternalizableString(
814 allocation, map) == allocation);
815 if (length < 0 || static_cast<uint32_t>(length) > String::kMaxLength) {
816 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError());
817 }
818 DCHECK_GT(length, 0); // Use Factory::empty_string() instead.
819 int size = SeqStringT::SizeFor(length);
821
822 Tagged<SeqStringT> string =
823 Cast<SeqStringT>(AllocateRawWithImmortalMap(size, allocation, map));
825 string->clear_padding_destructively(length);
826 string->set_length(length);
827 string->set_raw_hash_field(String::kEmptyHashField);
828 DCHECK_EQ(size, string->Size());
829 return handle(string, isolate());
830}
831
832template <typename Impl>
834 int length, AllocationType allocation) {
835 Tagged<Map> map = read_only_roots().seq_one_byte_string_map();
836 return NewRawStringWithMap<SeqOneByteString>(
837 length, map,
838 RefineAllocationTypeForInPlaceInternalizableString(allocation, map));
839}
840
841template <typename Impl>
843 int length, AllocationType allocation) {
844 Tagged<Map> map = read_only_roots().seq_two_byte_string_map();
845 return NewRawStringWithMap<SeqTwoByteString>(
846 length, map,
847 RefineAllocationTypeForInPlaceInternalizableString(allocation, map));
848}
849
850template <typename Impl>
852 int length) {
853 return NewRawStringWithMap<SeqOneByteString>(
854 length, read_only_roots().shared_seq_one_byte_string_map(),
856}
857
858template <typename Impl>
860 int length) {
861 return NewRawStringWithMap<SeqTwoByteString>(
862 length, read_only_roots().shared_seq_two_byte_string_map(),
864}
865
866template <typename Impl>
867template <template <typename> typename HandleType>
868 requires(std::is_convertible_v<HandleType<String>, DirectHandle<String>>)
869HandleType<String>::MaybeType FactoryBase<Impl>::NewConsString(
870 HandleType<String> left, HandleType<String> right,
871 AllocationType allocation) {
872 if (IsThinString(*left)) {
873 left = HandleType<String>(Cast<ThinString>(*left)->actual(), isolate());
874 }
875 if (IsThinString(*right)) {
876 right = HandleType<String>(Cast<ThinString>(*right)->actual(), isolate());
877 }
878 uint32_t left_length = left->length();
879 if (left_length == 0) return right;
880 uint32_t right_length = right->length();
881 if (right_length == 0) return left;
882
883 uint32_t length = left_length + right_length;
884
885 if (length == 2) {
886 uint16_t c1 = left->Get(0, isolate());
887 uint16_t c2 = right->Get(0, isolate());
888 return MakeOrFindTwoCharacterString(c1, c2);
889 }
890
891 // Make sure that an out of memory exception is thrown if the length
892 // of the new cons string is too large.
893 if (length > String::kMaxLength || length < 0) {
894 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError());
895 }
896
897 bool left_is_one_byte = left->IsOneByteRepresentation();
898 bool right_is_one_byte = right->IsOneByteRepresentation();
899 bool is_one_byte = left_is_one_byte && right_is_one_byte;
900
901 // If the resulting string is small make a flat string.
902 if (length < ConsString::kMinLength) {
903 // Note that neither of the two inputs can be a slice because:
905 DCHECK(left->IsFlat());
906 DCHECK(right->IsFlat());
907
909 if (is_one_byte) {
910 HandleType<SeqOneByteString> result =
911 NewRawOneByteString(length, allocation).ToHandleChecked();
914 uint8_t* dest = result->GetChars(no_gc, access_guard);
915 // Copy left part.
916 {
917 const uint8_t* src =
918 left->template GetDirectStringChars<uint8_t>(no_gc, access_guard);
919 CopyChars(dest, src, left_length);
920 }
921 // Copy right part.
922 {
923 const uint8_t* src =
924 right->template GetDirectStringChars<uint8_t>(no_gc, access_guard);
925 CopyChars(dest + left_length, src, right_length);
926 }
927 return result;
928 }
929
930 HandleType<SeqTwoByteString> result =
931 NewRawTwoByteString(length, allocation).ToHandleChecked();
932
935 base::uc16* sink = result->GetChars(no_gc, access_guard);
936 String::WriteToFlat(*left, sink, 0, left->length(), access_guard);
937 String::WriteToFlat(*right, sink + left->length(), 0, right->length(),
938 access_guard);
939 return result;
940 }
941
942 return NewConsString(left, right, length, is_one_byte, allocation);
943}
944
945template <typename Impl>
948 int length, bool one_byte,
949 AllocationType allocation) {
950 DCHECK(!IsThinString(*left));
951 DCHECK(!IsThinString(*right));
954
956 one_byte ? NewWithImmortalMap(
957 read_only_roots().cons_one_byte_string_map(), allocation)
958 : NewWithImmortalMap(
959 read_only_roots().cons_two_byte_string_map(), allocation));
960
962 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
963 result->set_raw_hash_field(String::kEmptyHashField);
964 result->set_length(length);
965 result->set_first(*left, mode);
966 result->set_second(*right, mode);
967 return handle(result, isolate());
968}
969
970template <typename Impl>
972 uint16_t code) {
973 if (code <= String::kMaxOneByteCharCode) {
974 return Cast<String>(
975 isolate()->root_handle(RootsTable::SingleCharacterStringIndex(code)));
976 }
977 uint16_t buffer[] = {code};
979}
980
981template <typename Impl>
983 base::Vector<const uint8_t> string, AllocationType allocation) {
985 int length = string.length();
986 if (length == 0) return empty_string();
987 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]);
990 NewRawOneByteString(string.length(), allocation));
991
993 // Copy the characters into the new object.
994 // SharedStringAccessGuardIfNeeded is NotNeeded because {result} is freshly
995 // allocated and hasn't escaped the factory yet, so it can't be concurrently
996 // accessed.
997 CopyChars(Cast<SeqOneByteString>(*result)->GetChars(
999 string.begin(), length);
1000 return result;
1001}
1002namespace {
1003
1004template <typename Impl>
1005V8_INLINE Handle<String> StringViewToString(FactoryBase<Impl>* factory,
1006 std::string_view string,
1007 NumberCacheMode mode) {
1008 // We tenure the allocated string since it is referenced from the
1009 // number-string cache which lives in the old space.
1013 return factory->NewStringFromAsciiChecked(string, type);
1014}
1015
1016} // namespace
1017
1018template <typename Impl>
1020 NumberCacheMode mode) {
1021 SLOW_DCHECK(IsNumber(*number));
1022 if (IsSmi(*number)) return SmiToString(Cast<Smi>(*number), mode);
1023
1024 double double_value = Cast<HeapNumber>(number)->value();
1025 // Try to canonicalize doubles.
1026 int smi_value;
1027 if (DoubleToSmiInteger(double_value, &smi_value)) {
1028 return SmiToString(Smi::FromInt(smi_value), mode);
1029 }
1030 return HeapNumberToString(Cast<HeapNumber>(number), double_value, mode);
1031}
1032
1033template <typename Impl>
1035 DirectHandle<HeapNumber> number, double value, NumberCacheMode mode) {
1036 int hash = mode == NumberCacheMode::kIgnore
1037 ? 0
1038 : impl()->NumberToStringCacheHash(value);
1039
1040 if (mode == NumberCacheMode::kBoth) {
1041 Handle<Object> cached = impl()->NumberToStringCacheGet(*number, hash);
1042 if (!IsUndefined(*cached, isolate())) return Cast<String>(cached);
1043 }
1044
1046 if (value == 0) {
1047 result = zero_string();
1048 } else if (std::isnan(value)) {
1049 result = NaN_string();
1050 } else {
1051 char arr[kNumberToStringBufferSize];
1052 base::Vector<char> buffer(arr, arraysize(arr));
1053 std::string_view string = DoubleToStringView(value, buffer);
1054 result = StringViewToString(this, string, mode);
1055 }
1056 if (mode != NumberCacheMode::kIgnore) {
1057 impl()->NumberToStringCacheSet(number, hash, result);
1058 }
1059 return result;
1060}
1061
1062template <typename Impl>
1064 NumberCacheMode mode) {
1065 int hash = mode == NumberCacheMode::kIgnore
1066 ? 0
1067 : impl()->NumberToStringCacheHash(number);
1068
1069 if (mode == NumberCacheMode::kBoth) {
1070 Handle<Object> cached = impl()->NumberToStringCacheGet(number, hash);
1071 if (!IsUndefined(*cached, isolate())) return Cast<String>(cached);
1072 }
1073
1075 if (number == Smi::zero()) {
1076 result = zero_string();
1077 } else {
1078 char arr[kNumberToStringBufferSize];
1079 base::Vector<char> buffer(arr, arraysize(arr));
1080 std::string_view string = IntToStringView(number.value(), buffer);
1081 result = StringViewToString(this, string, mode);
1082 }
1083 if (mode != NumberCacheMode::kIgnore) {
1084 impl()->NumberToStringCacheSet(direct_handle(number, isolate()), hash,
1085 result);
1086 }
1087
1088 // Compute the hash here (rather than letting the caller take care of it) so
1089 // that the "cache hit" case above doesn't have to bother with it.
1090 static_assert(Smi::kMaxValue <= std::numeric_limits<uint32_t>::max());
1091 {
1093 Tagged<String> raw = *result;
1094 if (raw->raw_hash_field() == String::kEmptyHashField &&
1095 number.value() >= 0) {
1096 uint32_t raw_hash_field = StringHasher::MakeArrayIndexHash(
1097 static_cast<uint32_t>(number.value()), raw->length());
1098 raw->set_raw_hash_field(raw_hash_field);
1099 }
1100 }
1101 return result;
1102}
1103
1104template <typename Impl>
1106 uint32_t length, AllocationType allocation) {
1107 if (length > BigInt::kMaxLength) {
1108 FATAL("Fatal JavaScript invalid size error %d", length);
1109 UNREACHABLE();
1110 }
1111 Tagged<HeapObject> result = AllocateRawWithImmortalMap(
1112 BigInt::SizeFor(length), allocation, read_only_roots().bigint_map());
1115 bigint->clear_padding();
1116 return handle(bigint, isolate());
1117}
1118
1119template <typename Impl>
1121 AllocationType type) {
1123 int size = ScopeInfo::SizeFor(length);
1124 Tagged<HeapObject> obj = AllocateRawWithImmortalMap(
1125 size, type, read_only_roots().scope_info_map());
1126 Tagged<ScopeInfo> scope_info = Cast<ScopeInfo>(obj);
1127 MemsetTagged(scope_info->data_start(), read_only_roots().undefined_value(),
1128 length);
1129#if TAGGED_SIZE_8_BYTES
1130 scope_info->set_optional_padding(0);
1131#endif
1132 return handle(scope_info, isolate());
1133}
1134
1135template <typename Impl>
1141
1142template <typename Impl>
1144 AllocationType allocation) {
1145 Tagged<Map> map = read_only_roots().shared_function_info_map();
1147 Cast<SharedFunctionInfo>(NewWithImmortalMap(map, allocation));
1148
1150 shared->Init(read_only_roots(), isolate()->GetAndIncNextUniqueSfiId());
1151 return handle(shared, isolate());
1152}
1153
1154template <typename Impl>
1156 int number_of_descriptors, int slack, AllocationType allocation) {
1157 int number_of_all_descriptors = number_of_descriptors + slack;
1158 // Zero-length case must be handled outside.
1159 DCHECK_LT(0, number_of_all_descriptors);
1160 int size = DescriptorArray::SizeFor(number_of_all_descriptors);
1161 Tagged<HeapObject> obj = AllocateRawWithImmortalMap(
1162 size, allocation, read_only_roots().descriptor_array_map());
1164
1166 if (allocation != AllocationType::kYoung &&
1167 allocation != AllocationType::kReadOnly) {
1168 auto* local_heap = allocation == AllocationType::kSharedOld
1170 : isolate()->heap();
1171 Heap* heap = local_heap->AsHeap();
1172 if (heap->incremental_marking()->IsMajorMarking()) {
1173 // Black allocation: We must create a full marked state.
1175 heap->mark_compact_collector()->epoch(), number_of_descriptors);
1176 }
1177 }
1178 array->Initialize(read_only_roots().empty_enum_cache(),
1179 read_only_roots().undefined_value(), number_of_descriptors,
1180 slack, raw_gc_state);
1181 return handle(array, isolate());
1182}
1183
1184template <typename Impl>
1186 int end) {
1187 auto result = NewStructInternal<ClassPositions>(CLASS_POSITIONS_TYPE,
1189 result->set_start(start);
1190 result->set_end(end);
1191 return handle(result, isolate());
1192}
1193
1194template <typename Impl>
1197 int length, uint32_t raw_hash_field) {
1199 // The canonical empty_string is the only zero-length string we allow.
1200 DCHECK_IMPLIES(length == 0, !impl()->EmptyStringRootIsInitialized());
1201
1202 Tagged<Map> map = read_only_roots().internalized_one_byte_string_map();
1203 const int size = SeqOneByteString::SizeFor(length);
1204 const AllocationType allocation =
1205 RefineAllocationTypeForInPlaceInternalizableString(
1206 impl()->CanAllocateInReadOnlySpace() ? AllocationType::kReadOnly
1208 map);
1209 Tagged<HeapObject> result = AllocateRawWithImmortalMap(size, allocation, map);
1212 answer->clear_padding_destructively(length);
1213 answer->set_length(length);
1214 answer->set_raw_hash_field(raw_hash_field);
1215 DCHECK_EQ(size, answer->Size());
1216 return handle(answer, isolate());
1217}
1218
1219template <typename Impl>
1222 int length, uint32_t raw_hash_field) {
1224 DCHECK_NE(0, length); // Use Heap::empty_string() instead.
1225
1226 Tagged<Map> map = read_only_roots().internalized_two_byte_string_map();
1227 int size = SeqTwoByteString::SizeFor(length);
1229 Cast<SeqTwoByteString>(AllocateRawWithImmortalMap(
1230 size,
1231 RefineAllocationTypeForInPlaceInternalizableString(
1233 map));
1235 answer->clear_padding_destructively(length);
1236 answer->set_length(length);
1237 answer->set_raw_hash_field(raw_hash_field);
1238 DCHECK_EQ(size, answer->Size());
1239 return handle(answer, isolate());
1240}
1241
1242template <typename Impl>
1244 int size, AllocationType allocation) {
1245 Tagged<HeapObject> result = AllocateRaw(size, allocation);
1246 if ((size >
1247 isolate()->heap()->AsHeap()->MaxRegularHeapObjectSize(allocation)) &&
1248 v8_flags.use_marking_progress_bar) {
1251 .Enable(size);
1252 }
1253 return result;
1254}
1255
1256template <typename Impl>
1258 int length, AllocationType allocation) {
1260 FATAL("Fatal JavaScript invalid size error %d", length);
1261 UNREACHABLE();
1262 }
1263 return AllocateRawArray(FixedArray::SizeFor(length), allocation);
1264}
1265
1266template <typename Impl>
1268 int capacity, AllocationType allocation) {
1269 if (capacity < 0 || capacity > WeakArrayList::kMaxCapacity) {
1270 FATAL("Fatal JavaScript invalid size error %d", capacity);
1271 UNREACHABLE();
1272 }
1273 return AllocateRawArray(WeakArrayList::SizeForCapacity(capacity), allocation);
1274}
1275
1276template <typename Impl>
1278 Tagged<Map> map, AllocationType allocation) {
1279 return AllocateRawWithImmortalMap(map->instance_size(), allocation, map);
1280}
1281
1282template <typename Impl>
1284 int size, AllocationType allocation, Tagged<Map> map,
1285 AllocationAlignment alignment) {
1286 // TODO(delphick): Potentially you could also pass an immortal immovable Map
1287 // from OLD_SPACE here, like external_map or message_object_map, but currently
1288 // no one does so this check is sufficient.
1290 Tagged<HeapObject> result = AllocateRaw(size, allocation, alignment);
1292 result->set_map_after_allocation(isolate(), map, SKIP_WRITE_BARRIER);
1293 return result;
1294}
1295
1296template <typename Impl>
1298 int size, AllocationType allocation, AllocationAlignment alignment) {
1299 return impl()->AllocateRaw(size, allocation, alignment);
1300}
1301
1302template <typename Impl>
1305 int capacity, AllocationType allocation) {
1307
1308 if (capacity == 0) {
1309 DCHECK_NE(
1310 read_only_roots().address_at(RootIndex::kEmptySwissPropertyDictionary),
1311 kNullAddress);
1312
1313 return empty_swiss_property_dictionary();
1314 }
1315
1316 if (capacity < 0 || capacity > SwissNameDictionary::MaxCapacity()) {
1317 FATAL("Fatal JavaScript invalid size error %d", capacity);
1318 UNREACHABLE();
1319 }
1320
1321 int meta_table_length = SwissNameDictionary::MetaTableSizeFor(capacity);
1322 DirectHandle<ByteArray> meta_table =
1323 impl()->NewByteArray(meta_table_length, allocation);
1324
1325 Tagged<Map> map = read_only_roots().swiss_name_dictionary_map();
1326 int size = SwissNameDictionary::SizeFor(capacity);
1328 AllocateRawWithImmortalMap(size, allocation, map));
1330 table->Initialize(isolate(), *meta_table, capacity);
1331 return handle(table, isolate());
1332}
1333
1334template <typename Impl>
1336 int at_least_space_for, AllocationType allocation) {
1337 return NewSwissNameDictionaryWithCapacity(
1338 SwissNameDictionary::CapacityFor(at_least_space_for), allocation);
1339}
1340
1341template <typename Impl>
1344 auto function_template_rare_data =
1345 NewStructInternal<FunctionTemplateRareData>(
1346 FUNCTION_TEMPLATE_RARE_DATA_TYPE, AllocationType::kOld);
1348 function_template_rare_data->set_c_function_overloads(
1349 *impl()->empty_fixed_array(), SKIP_WRITE_BARRIER);
1350 return direct_handle(function_template_rare_data, isolate());
1351}
1352
1353template <typename Impl>
1355 Tagged<Map> from_string_map) {
1356 InstanceType instance_type = from_string_map->instance_type();
1358 switch (instance_type) {
1361 map = internalized_two_byte_string_map();
1362 break;
1365 map = internalized_one_byte_string_map();
1366 break;
1369 map = external_internalized_two_byte_string_map();
1370 break;
1373 map = external_internalized_one_byte_string_map();
1374 break;
1375 default:
1376 break;
1377 }
1378 DCHECK_EQ(!map.is_null(), String::IsInPlaceInternalizable(instance_type));
1379 return map;
1380}
1381
1382template <typename Impl>
1385 AllocationType allocation, Tagged<Map> string_map) {
1386#ifdef DEBUG
1387 InstanceType instance_type = string_map->instance_type();
1389 String::IsInPlaceInternalizable(instance_type));
1390#endif
1391 if (v8_flags.single_generation && allocation == AllocationType::kYoung) {
1392 allocation = AllocationType::kOld;
1393 }
1394 if (allocation != AllocationType::kOld) return allocation;
1395 return impl()->AllocationTypeForInPlaceInternalizableString();
1396}
1397
1398#ifdef V8_ENABLE_LEAPTIERING
1399template <typename Impl>
1401 uint16_t parameter_count, DirectHandle<Code> code,
1402 JSDispatchTable::Space* space) {
1403 JSDispatchTable* jdt = isolate()->isolate_group()->js_dispatch_table();
1404 auto Allocate = [&](AllocationType _) {
1405 return jdt->TryAllocateAndInitializeEntry(space, parameter_count, *code);
1406 };
1407 // Dispatch entries are only freed on major GCs.
1409 auto allocator = isolate()->heap()->allocator();
1410 return allocator->CustomAllocateWithRetryOrFail(Allocate, type);
1411}
1412#endif // V8_ENABLE_LEAPTIERING
1413
1414// Instantiate FactoryBase for the two variants we want.
1415template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) FactoryBase<Factory>;
1417 FactoryBase<LocalFactory>;
1418
1422 AllocationType allocation);
1423template V8_EXPORT_PRIVATE MaybeDirectHandle<String>
1424FactoryBase<Factory>::NewConsString(DirectHandle<String> left,
1425 DirectHandle<String> right,
1426 AllocationType allocation);
1430 AllocationType allocation);
1431template V8_EXPORT_PRIVATE MaybeDirectHandle<String>
1432FactoryBase<LocalFactory>::NewConsString(DirectHandle<String> left,
1433 DirectHandle<String> right,
1434 AllocationType allocation);
1435
1436} // namespace internal
1437} // namespace v8
int16_t parameter_count
Definition builtins.cc:67
Builtins::Kind kind
Definition builtins.cc:40
#define SBXCHECK_IMPLIES(when, then)
Definition check.h:69
#define SLOW_DCHECK(condition)
Definition checks.h:21
static const uint16_t kMaxChar
Definition unicode.h:142
int length() const
Definition vector.h:64
constexpr T * begin() const
Definition vector.h:96
static DirectHandle< ArrayList > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung)
static const uint32_t kMaxLength
Definition bigint.h:106
static uint32_t SizeFor(uint32_t length)
Definition bigint.h:252
static constexpr bool IsBuiltinId(Builtin builtin)
Definition builtins.h:128
static bool CheckFormalParameterCount(Builtin builtin, int function_length, int formal_parameter_count_with_receiver)
Definition builtins.cc:166
static Handle< ByteArray > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung)
static constexpr int SizeFor(int length)
static const uint32_t kMinLength
Definition string.h:1029
static int SizeFor(int slot_count)
static constexpr RawGCStateType GetFullyMarkedState(unsigned epoch, DescriptorIndex number_of_descriptors)
static constexpr RawGCStateType kInitialGCState
static constexpr int SizeFor(int number_of_all_descriptors)
MaybeHandle< String > NewStringFromOneByte(base::Vector< const uint8_t > string, AllocationType allocation=AllocationType::kYoung)
V8_WARN_UNUSED_RESULT Handle< String > NumberToString(DirectHandle< Object > number, NumberCacheMode mode=NumberCacheMode::kBoth)
Tagged< HeapObject > AllocateRawWithImmortalMap(int size, AllocationType allocation, Tagged< Map > map, AllocationAlignment alignment=kTaggedAligned)
Tagged< HeapObject > AllocateRawFixedArray(int length, AllocationType allocation)
DirectHandle< RegExpBoilerplateDescription > NewRegExpBoilerplateDescription(DirectHandle< RegExpData > data, DirectHandle< String > source, Tagged< Smi > flags)
DirectHandle< UncompiledDataWithPreparseDataAndJob > NewUncompiledDataWithPreparseDataAndJob(Handle< String > inferred_name, int32_t start_position, int32_t end_position, Handle< PreparseData >)
Handle< SharedFunctionInfo > NewSharedFunctionInfo(AllocationType allocation)
Handle< WeakFixedArray > NewWeakFixedArrayWithMap(Tagged< Map > map, int length, AllocationType allocation=AllocationType::kYoung)
DirectHandle< RegExpDataWrapper > NewRegExpDataWrapper()
Handle< AccessorPair > NewAccessorPair()
Handle< String > MakeOrFindTwoCharacterString(uint16_t c1, uint16_t c2)
DirectHandle< FunctionTemplateRareData > NewFunctionTemplateRareData()
Handle< SharedFunctionInfo > CloneSharedFunctionInfo(DirectHandle< SharedFunctionInfo > other)
V8_WARN_UNUSED_RESULT HandleType< String >::MaybeType NewConsString(HandleType< String > left, HandleType< String > right, AllocationType allocation=AllocationType::kYoung)
Handle< String > NewStringFromAsciiChecked(const char *str, AllocationType allocation=AllocationType::kYoung)
DirectHandle< SeqOneByteString > NewOneByteInternalizedStringFromTwoByte(base::Vector< const base::uc16 > str, uint32_t raw_hash_field)
Tagged< HeapObject > NewWithImmortalMap(Tagged< Map > map, AllocationType allocation)
Tagged< HeapObject > AllocateRaw(int size, AllocationType allocation, AllocationAlignment alignment=kTaggedAligned)
V8_WARN_UNUSED_RESULT Handle< String > SmiToString(Tagged< Smi > number, NumberCacheMode mode=NumberCacheMode::kBoth)
Handle< ArrayBoilerplateDescription > NewArrayBoilerplateDescription(ElementsKind elements_kind, DirectHandle< FixedArrayBase > constant_values)
DirectHandle< DeoptimizationLiteralArray > NewDeoptimizationLiteralArray(int length)
Tagged< HeapObject > AllocateRawArray(int size, AllocationType allocation)
DirectHandle< DeoptimizationFrameTranslation > NewDeoptimizationFrameTranslation(int length)
Handle< Code > NewCode(const NewCodeOptions &options)
Handle< String > LookupSingleCharacterStringFromCode(uint16_t code)
V8_WARN_UNUSED_RESULT MaybeHandle< SeqOneByteString > NewRawOneByteString(int length, AllocationType allocation=AllocationType::kYoung)
Handle< TemplateObjectDescription > NewTemplateObjectDescription(DirectHandle< FixedArray > raw_strings, DirectHandle< FixedArray > cooked_strings)
Handle< FixedArray > NewFixedArrayWithMap(DirectHandle< Map > map, int length, AllocationType allocation=AllocationType::kYoung)
Handle< ProtectedFixedArray > NewProtectedFixedArray(int length)
Handle< SwissNameDictionary > NewSwissNameDictionary(int at_least_space_for=kSwissNameDictionaryInitialCapacity, AllocationType allocation=AllocationType::kYoung)
Handle< ScopeInfo > NewScopeInfo(int length, AllocationType type=AllocationType::kOld)
Handle< TrustedFixedArray > NewTrustedFixedArray(int length, AllocationType allocation=AllocationType::kTrusted)
V8_WARN_UNUSED_RESULT Handle< String > HeapNumberToString(DirectHandle< HeapNumber > number, double value, NumberCacheMode mode=NumberCacheMode::kBoth)
Handle< ByteArray > NewByteArray(int length, AllocationType allocation=AllocationType::kYoung)
Handle< PreparseData > NewPreparseData(int data_length, int children_length)
Handle< Script > NewScriptWithId(DirectHandle< UnionOf< String, Undefined > > source, int script_id, ScriptEventType event_type=ScriptEventType::kCreate)
MaybeHandle< SeqStringT > NewRawStringWithMap(int length, Tagged< Map > map, AllocationType allocation)
Tagged< HeapObject > AllocateRawWeakArrayList(int length, AllocationType allocation)
DirectHandle< BytecodeWrapper > NewBytecodeWrapper(AllocationType allocation=AllocationType::kOld)
Handle< String > InternalizeString(base::Vector< const uint8_t > string, bool convert_encoding=false)
DirectHandle< SourceTextModuleInfo > NewSourceTextModuleInfo()
Handle< DescriptorArray > NewDescriptorArray(int number_of_descriptors, int slack=0, AllocationType allocation=AllocationType::kYoung)
DirectHandle< UncompiledDataWithoutPreparseData > NewUncompiledDataWithoutPreparseData(Handle< String > inferred_name, int32_t start_position, int32_t end_position)
Handle< SharedFunctionInfo > NewSharedFunctionInfoForLiteral(FunctionLiteral *literal, DirectHandle< Script > script, bool is_toplevel)
DirectHandle< CodeWrapper > NewCodeWrapper()
Handle< FreshlyAllocatedBigInt > NewBigInt(uint32_t length, AllocationType allocation=AllocationType::kYoung)
Handle< SeqOneByteString > NewOneByteInternalizedString(base::Vector< const uint8_t > str, uint32_t raw_hash_field)
MaybeDirectHandle< Map > GetInPlaceInternalizedStringMap(Tagged< Map > from_string_map)
Handle< ObjectBoilerplateDescription > NewObjectBoilerplateDescription(int boilerplate, int all_properties, int index_keys, bool has_seen_proto)
Handle< SeqOneByteString > AllocateRawOneByteInternalizedString(int length, uint32_t raw_hash_field)
V8_WARN_UNUSED_RESULT MaybeHandle< SeqOneByteString > NewRawSharedOneByteString(int length)
DirectHandle< SloppyArgumentsElements > NewSloppyArgumentsElements(int length, DirectHandle< Context > context, DirectHandle< FixedArray > arguments, AllocationType allocation=AllocationType::kYoung)
DirectHandle< ArrayList > NewArrayList(int size, AllocationType allocation=AllocationType::kYoung)
Handle< WeakFixedArray > NewWeakFixedArray(int length, AllocationType allocation=AllocationType::kYoung)
Handle< FixedArray > NewFixedArrayWithHoles(int length, AllocationType allocation=AllocationType::kYoung)
DirectHandle< SharedFunctionInfoWrapper > NewSharedFunctionInfoWrapper(DirectHandle< SharedFunctionInfo > sfi)
AllocationType RefineAllocationTypeForInPlaceInternalizableString(AllocationType allocation, Tagged< Map > string_map)
Handle< BytecodeArray > NewBytecodeArray(int length, const uint8_t *raw_bytecodes, int frame_size, uint16_t parameter_count, uint16_t max_arguments, DirectHandle< TrustedFixedArray > constant_pool, DirectHandle< TrustedByteArray > handler_table, AllocationType allocation=AllocationType::kTrusted)
DirectHandle< UncompiledDataWithoutPreparseDataWithJob > NewUncompiledDataWithoutPreparseDataWithJob(Handle< String > inferred_name, int32_t start_position, int32_t end_position)
Handle< FixedArrayBase > NewFixedDoubleArray(int length, AllocationType allocation=AllocationType::kYoung)
V8_WARN_UNUSED_RESULT MaybeHandle< SeqTwoByteString > NewRawTwoByteString(int length, AllocationType allocation=AllocationType::kYoung)
Handle< Struct > NewStruct(InstanceType type, AllocationType allocation=AllocationType::kYoung)
V8_WARN_UNUSED_RESULT MaybeHandle< SeqTwoByteString > NewRawSharedTwoByteString(int length)
Handle< Script > NewScript(DirectHandle< UnionOf< String, Undefined > > source, ScriptEventType event_type=ScriptEventType::kCreate)
Handle< ClassPositions > NewClassPositions(int start, int end)
Handle< FixedArray > NewFixedArrayWithFiller(DirectHandle< Map > map, int length, DirectHandle< HeapObject > filler, AllocationType allocation)
Handle< ProtectedWeakFixedArray > NewProtectedWeakFixedArray(int length)
Handle< TrustedWeakFixedArray > NewTrustedWeakFixedArray(int length)
Handle< SeqTwoByteString > NewTwoByteInternalizedString(base::Vector< const base::uc16 > str, uint32_t raw_hash_field)
Handle< FixedArray > NewFixedArray(int length, AllocationType allocation=AllocationType::kYoung)
Handle< SeqTwoByteString > AllocateRawTwoByteInternalizedString(int length, uint32_t raw_hash_field)
Handle< FeedbackMetadata > NewFeedbackMetadata(int slot_count, int create_closure_slot_count, AllocationType allocation=AllocationType::kOld)
DirectHandle< FixedArray > NewFixedArrayWithZeroes(int length, AllocationType allocation=AllocationType::kYoung)
Handle< SwissNameDictionary > NewSwissNameDictionaryWithCapacity(int capacity, AllocationType allocation)
Handle< CoverageInfo > NewCoverageInfo(const ZoneVector< SourceRange > &slots)
Handle< TrustedByteArray > NewTrustedByteArray(int length, AllocationType allocation_type=AllocationType::kTrusted)
Handle< String > InternalizeStringWithKey(StringTableKey *key)
Handle< HeapNumber > NewHeapNumber()
DirectHandle< UncompiledDataWithPreparseData > NewUncompiledDataWithPreparseData(Handle< String > inferred_name, int32_t start_position, int32_t end_position, Handle< PreparseData >)
static int SizeFor(int slot_count, int create_closure_slot_count)
static constexpr int kMaxLength
static Handle< FixedArray > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung)
static Handle< FixedArrayBase > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung)
FunctionKind kind() const
Definition ast.cc:231
int function_literal_id() const
Definition ast.h:2408
MaybeHandle< String > GetName(IsolateT *isolate) const
Definition ast.h:2309
void set_shared_function_info(Handle< SharedFunctionInfo > shared_function_info)
Definition ast.cc:202
V8_WARN_UNUSED_RESULT V8_INLINE auto CustomAllocateWithRetryOrFail(Function &&Allocate, AllocationType allocation)
static constexpr int kHeaderSize
HeapAllocator * allocator()
Definition heap.h:1640
IsolateGroup * isolate_group() const
Definition isolate.h:1230
Isolate * shared_space_isolate() const
Definition isolate.h:2295
static V8_INLINE LargePageMetadata * FromHeapObject(Tagged< HeapObject > o)
static Tagged< Map > GetMapFor(ReadOnlyRoots roots, InstanceType type)
Definition map-inl.h:855
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
MarkingProgressTracker & marking_progress_tracker()
static constexpr int kEmptyHashField
Definition name.h:133
static Handle< ObjectBoilerplateDescription > New(IsolateT *isolate, int boilerplate, int all_properties, int index_keys, bool has_seen_proto, AllocationType allocation=AllocationType::kYoung)
static int SizeFor(int data_length, int children_length)
static Handle< ProtectedFixedArray > New(IsolateT *isolate, int capacity)
static Handle< ProtectedWeakFixedArray > New(IsolateT *isolate, int capacity)
static V8_EXPORT_PRIVATE bool Contains(Address address)
static constexpr RootIndex SingleCharacterStringIndex(int c)
Definition roots.h:629
static constexpr int SizeFor(int length)
Definition scope-info.h:299
static V8_INLINE constexpr int32_t SizeFor(int32_t length)
static V8_INLINE constexpr int32_t SizeFor(int32_t length)
static V8_EXPORT_PRIVATE constexpr Tagged< Smi > const kNoSharedNameSentinel
static void InitFromFunctionLiteral(IsolateT *isolate, FunctionLiteral *lit, bool is_toplevel)
static SharedStringAccessGuardIfNeeded NotNeeded()
Definition string-inl.h:72
static const uint32_t kMinLength
Definition string.h:1130
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
static constexpr Tagged< Smi > zero()
Definition smi.h:99
static V8_INLINE uint32_t MakeArrayIndexHash(uint32_t value, uint32_t length)
static void WriteToFlat(Tagged< String > source, SinkCharT *sink, uint32_t start, uint32_t length)
Definition string.cc:772
static const uint32_t kMaxLength
Definition string.h:511
static const int32_t kMaxOneByteCharCode
Definition string.h:500
static bool IsInPlaceInternalizable(Tagged< String > string)
static constexpr bool IsValidCapacity(int capacity)
static int CapacityFor(int at_least_space_for)
static constexpr int SizeFor(int capacity)
static constexpr int MetaTableSizeFor(int capacity)
static Handle< TrustedByteArray > New(IsolateT *isolate, int capacity, AllocationType allocation_type=AllocationType::kTrusted)
static Handle< TrustedFixedArray > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kTrusted)
static Handle< TrustedWeakFixedArray > New(IsolateT *isolate, int capacity)
static constexpr int SizeForCapacity(int capacity)
static constexpr int kMaxCapacity
static Handle< WeakFixedArray > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung, MaybeDirectHandle< Object > initial_value={})
static constexpr Register invalid_value()
int start
int end
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:291
#define THROW_NEW_ERROR(isolate, call)
Definition isolate.h:307
#define EXPORT_TEMPLATE_DEFINE(export)
Isolate * isolate
SharedFunctionInfoRef shared
#define _
std::map< const std::string, const std::string > map
ZoneVector< RpoNumber > & result
FunctionLiteral * literal
Definition liveedit.cc:294
constexpr int kUC16Size
Definition strings.h:20
uint16_t uc16
Definition strings.h:18
V8_INLINE constexpr bool IsInternalizedString(InstanceType instance_type)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
void CopyBytes(T *dst, const T *src, size_t num_bytes)
Definition memcopy.h:261
constexpr int kMaxRegularHeapObjectSize
Definition globals.h:680
@ SKIP_WRITE_BARRIER
Definition objects.h:52
@ UPDATE_WRITE_BARRIER
Definition objects.h:55
SlotTraits::TObjectSlot ObjectSlot
Definition globals.h:1243
bool DoubleToSmiInteger(double value, int *smi_int_value)
bool IsNumber(Tagged< Object > obj)
MaybeHandle< T > MaybeIndirectHandle
Definition globals.h:1109
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:665
V8_INLINE IndirectHandle< T > indirect_handle(DirectHandle< T > handle)
Definition handles.h:757
std::string_view IntToStringView(int n, base::Vector< char > buffer)
void MemsetTagged(Tagged_t *start, Tagged< MaybeObject > value, size_t counter)
Definition slots-inl.h:486
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
Handle< T > IndirectHandle
Definition globals.h:1086
constexpr JSDispatchHandle kNullJSDispatchHandle(0)
bool IsShared(Tagged< Object > obj)
constexpr AdaptArguments kDontAdapt
Definition globals.h:2776
constexpr bool CodeKindMayLackSourcePositionTable(CodeKind kind)
Definition code-kind.h:117
typename detail::FlattenUnionHelper< Union<>, Ts... >::type UnionOf
Definition union.h:123
@ SHARED_SEQ_ONE_BYTE_STRING_TYPE
@ SHARED_SEQ_TWO_BYTE_STRING_TYPE
@ SHARED_EXTERNAL_TWO_BYTE_STRING_TYPE
@ EXTERNAL_TWO_BYTE_STRING_TYPE
@ SHARED_EXTERNAL_ONE_BYTE_STRING_TYPE
@ EXTERNAL_ONE_BYTE_STRING_TYPE
void CopyChars(DstType *dst, const SrcType *src, size_t count) V8_NONNULL(1
constexpr bool CodeKindUsesBytecodeOrInterpreterData(CodeKind kind)
Definition code-kind.h:105
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr int JSParameterCount(int param_count_without_receiver)
Definition globals.h:2782
std::string_view DoubleToStringView(double v, base::Vector< char > buffer)
uint64_t HashSeed(Isolate *isolate)
static constexpr Address kNullAddress
Definition v8-internal.h:53
void MemCopy(void *dest, const void *src, size_t size)
Definition memcopy.h:124
constexpr bool CodeKindUsesDeoptimizationData(CodeKind kind)
Definition code-kind.h:109
constexpr bool CodeKindUsesBytecodeOffsetTable(CodeKind kind)
Definition code-kind.h:113
kInterpreterTrampolineOffset script
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
static constexpr ReleaseStoreTag kReleaseStore
Definition globals.h:2910
Local< T > Handle
static constexpr AcquireLoadTag kAcquireLoad
Definition globals.h:2908
#define FATAL(...)
Definition logging.h:47
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define CHECK_GE(lhs, rhs)
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define DCHECK_GT(v1, v2)
Definition logging.h:487
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define arraysize(array)
Definition macros.h:67
#define V8_INLINE
Definition v8config.h:500