// Copyright 2020 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/heap/factory-base.h" #include "src/ast/ast-source-ranges.h" #include "src/ast/ast.h" #include "src/execution/off-thread-isolate.h" #include "src/handles/handles-inl.h" #include "src/heap/factory.h" #include "src/heap/heap-inl.h" #include "src/heap/memory-chunk.h" #include "src/heap/off-thread-factory-inl.h" #include "src/heap/read-only-heap.h" #include "src/logging/log.h" #include "src/logging/off-thread-logger.h" #include "src/objects/literal-objects-inl.h" #include "src/objects/module-inl.h" #include "src/objects/oddball.h" #include "src/objects/shared-function-info-inl.h" #include "src/objects/source-text-module.h" #include "src/objects/template-objects-inl.h" namespace v8 { namespace internal { template template Handle FactoryBase::NewHeapNumber() { STATIC_ASSERT(HeapNumber::kSize <= kMaxRegularHeapObjectSize); Map map = read_only_roots().heap_number_map(); HeapObject result = AllocateRawWithImmortalMap(HeapNumber::kSize, allocation, map, kDoubleUnaligned); return handle(HeapNumber::cast(result), isolate()); } template V8_EXPORT_PRIVATE Handle FactoryBase::NewHeapNumber(); template V8_EXPORT_PRIVATE Handle FactoryBase::NewHeapNumber(); template V8_EXPORT_PRIVATE Handle FactoryBase::NewHeapNumber(); template V8_EXPORT_PRIVATE Handle FactoryBase::NewHeapNumber(); template Handle FactoryBase::NewStruct(InstanceType type, AllocationType allocation) { Map map = Map::GetInstanceTypeMap(read_only_roots(), type); int size = map.instance_size(); HeapObject result = AllocateRawWithImmortalMap(size, allocation, map); Handle str = handle(Struct::cast(result), isolate()); str->InitializeBody(size); return str; } template Handle FactoryBase::NewAccessorPair() { Handle accessors = Handle::cast( NewStruct(ACCESSOR_PAIR_TYPE, AllocationType::kOld)); accessors->set_getter(read_only_roots().null_value(), SKIP_WRITE_BARRIER); accessors->set_setter(read_only_roots().null_value(), SKIP_WRITE_BARRIER); return accessors; } template Handle FactoryBase::NewFixedArray(int length, AllocationType allocation) { DCHECK_LE(0, length); if (length == 0) return impl()->empty_fixed_array(); return NewFixedArrayWithFiller( read_only_roots().fixed_array_map_handle(), length, read_only_roots().undefined_value_handle(), allocation); } template Handle FactoryBase::NewFixedArrayWithMap( Handle map, int length, AllocationType allocation) { // Zero-length case must be handled outside, where the knowledge about // the map is. DCHECK_LT(0, length); return NewFixedArrayWithFiller( map, length, read_only_roots().undefined_value_handle(), allocation); } template Handle FactoryBase::NewFixedArrayWithHoles( int length, AllocationType allocation) { DCHECK_LE(0, length); if (length == 0) return impl()->empty_fixed_array(); return NewFixedArrayWithFiller( read_only_roots().fixed_array_map_handle(), length, read_only_roots().the_hole_value_handle(), allocation); } template Handle FactoryBase::NewFixedArrayWithFiller( Handle map, int length, Handle filler, AllocationType allocation) { HeapObject result = AllocateRawFixedArray(length, allocation); DCHECK(ReadOnlyHeap::Contains(*map)); DCHECK(ReadOnlyHeap::Contains(*filler)); result.set_map_after_allocation(*map, SKIP_WRITE_BARRIER); Handle array = handle(FixedArray::cast(result), isolate()); array->set_length(length); MemsetTagged(array->data_start(), *filler, length); return array; } template Handle FactoryBase::NewFixedDoubleArray( int length, AllocationType allocation) { if (length == 0) return impl()->empty_fixed_array(); if (length < 0 || length > FixedDoubleArray::kMaxLength) { isolate()->FatalProcessOutOfHeapMemory("invalid array length"); } int size = FixedDoubleArray::SizeFor(length); Map map = read_only_roots().fixed_double_array_map(); HeapObject result = AllocateRawWithImmortalMap(size, allocation, map, kDoubleAligned); Handle array = handle(FixedDoubleArray::cast(result), isolate()); array->set_length(length); return array; } template Handle FactoryBase::NewWeakFixedArrayWithMap( Map map, int length, AllocationType allocation) { // Zero-length case must be handled outside. DCHECK_LT(0, length); DCHECK(ReadOnlyHeap::Contains(map)); HeapObject result = AllocateRawArray(WeakFixedArray::SizeFor(length), allocation); result.set_map_after_allocation(map, SKIP_WRITE_BARRIER); Handle array = handle(WeakFixedArray::cast(result), isolate()); array->set_length(length); MemsetTagged(ObjectSlot(array->data_start()), read_only_roots().undefined_value(), length); return array; } template Handle FactoryBase::NewWeakFixedArray( int length, AllocationType allocation) { DCHECK_LE(0, length); if (length == 0) return impl()->empty_weak_fixed_array(); return NewWeakFixedArrayWithMap(read_only_roots().weak_fixed_array_map(), length, allocation); } template Handle FactoryBase::NewByteArray(int length, AllocationType allocation) { if (length < 0 || length > ByteArray::kMaxLength) { isolate()->FatalProcessOutOfHeapMemory("invalid array length"); } int size = ByteArray::SizeFor(length); HeapObject result = AllocateRawWithImmortalMap( size, allocation, read_only_roots().byte_array_map()); Handle array(ByteArray::cast(result), isolate()); array->set_length(length); array->clear_padding(); return array; } template Handle FactoryBase::NewBytecodeArray( int length, const byte* raw_bytecodes, int frame_size, int parameter_count, Handle constant_pool) { if (length < 0 || length > BytecodeArray::kMaxLength) { isolate()->FatalProcessOutOfHeapMemory("invalid array length"); } // Bytecode array is AllocationType::kOld, so constant pool array should be // too. DCHECK(!Heap::InYoungGeneration(*constant_pool)); int size = BytecodeArray::SizeFor(length); HeapObject result = AllocateRawWithImmortalMap( size, AllocationType::kOld, read_only_roots().bytecode_array_map()); Handle instance(BytecodeArray::cast(result), isolate()); instance->set_length(length); instance->set_frame_size(frame_size); instance->set_parameter_count(parameter_count); instance->set_incoming_new_target_or_generator_register( interpreter::Register::invalid_value()); instance->set_osr_loop_nesting_level(0); instance->set_bytecode_age(BytecodeArray::kNoAgeBytecodeAge); instance->set_constant_pool(*constant_pool); instance->set_handler_table(read_only_roots().empty_byte_array()); instance->set_source_position_table(read_only_roots().undefined_value()); CopyBytes(reinterpret_cast(instance->GetFirstBytecodeAddress()), raw_bytecodes, length); instance->clear_padding(); return instance; } template Handle