diff options
Diffstat (limited to 'deps/v8/src/heap/factory.cc')
-rw-r--r-- | deps/v8/src/heap/factory.cc | 324 |
1 files changed, 197 insertions, 127 deletions
diff --git a/deps/v8/src/heap/factory.cc b/deps/v8/src/heap/factory.cc index f82d8937c3..6dea2cae31 100644 --- a/deps/v8/src/heap/factory.cc +++ b/deps/v8/src/heap/factory.cc @@ -14,10 +14,15 @@ #include "src/compiler.h" #include "src/conversions.h" #include "src/counters.h" +#include "src/hash-seed-inl.h" +#include "src/heap/heap-inl.h" +#include "src/heap/incremental-marking.h" #include "src/heap/mark-compact-inl.h" +#include "src/ic/handler-configuration-inl.h" #include "src/interpreter/interpreter.h" #include "src/isolate-inl.h" #include "src/log.h" +#include "src/objects/allocation-site-inl.h" #include "src/objects/api-callbacks.h" #include "src/objects/arguments-inl.h" #include "src/objects/bigint.h" @@ -41,8 +46,10 @@ #include "src/objects/scope-info.h" #include "src/objects/stack-frame-info-inl.h" #include "src/objects/struct-inl.h" +#include "src/objects/template-objects-inl.h" +#include "src/transitions-inl.h" #include "src/unicode-cache.h" -#include "src/unicode-decoder.h" +#include "src/unicode-inl.h" namespace v8 { namespace internal { @@ -71,28 +78,27 @@ void InitializeCode(Heap* heap, Handle<Code> code, int object_size, Handle<DeoptimizationData> deopt_data, Handle<ByteArray> reloc_info, Handle<CodeDataContainer> data_container, - bool is_turbofanned, int stack_slots, - int safepoint_table_offset, int handler_table_offset) { + bool is_turbofanned, int stack_slots) { DCHECK(IsAligned(code->address(), kCodeAlignment)); DCHECK_IMPLIES( !heap->memory_allocator()->code_range().is_empty(), heap->memory_allocator()->code_range().contains(code->address())); - bool has_unwinding_info = desc.unwinding_info != nullptr; + constexpr bool kIsNotOffHeapTrampoline = false; + const bool has_unwinding_info = desc.unwinding_info != nullptr; code->set_raw_instruction_size(desc.instr_size); code->set_relocation_info(*reloc_info); - const bool is_off_heap_trampoline = false; code->initialize_flags(kind, has_unwinding_info, is_turbofanned, stack_slots, - is_off_heap_trampoline); - code->set_safepoint_table_offset(safepoint_table_offset); - code->set_handler_table_offset(handler_table_offset); + kIsNotOffHeapTrampoline); + code->set_builtin_index(builtin_index); code->set_code_data_container(*data_container); code->set_deoptimization_data(*deopt_data); code->set_source_position_table(*source_position_table); - code->set_constant_pool_offset(desc.constant_pool_offset()); - code->set_code_comments_offset(desc.code_comments_offset()); - code->set_builtin_index(builtin_index); + code->set_safepoint_table_offset(desc.safepoint_table_offset); + code->set_handler_table_offset(desc.handler_table_offset); + code->set_constant_pool_offset(desc.constant_pool_offset); + code->set_code_comments_offset(desc.code_comments_offset); // Allow self references to created code object by patching the handle to // point to the newly allocated Code object. @@ -126,8 +132,9 @@ void InitializeCode(Heap* heap, Handle<Code> code, int object_size, HeapObject Factory::AllocateRawWithImmortalMap(int size, PretenureFlag pretenure, Map map, AllocationAlignment alignment) { - HeapObject result = isolate()->heap()->AllocateRawWithRetryOrFail( - size, Heap::SelectSpace(pretenure), alignment); + AllocationType type = Heap::SelectType(Heap::SelectSpace(pretenure)); + HeapObject result = + isolate()->heap()->AllocateRawWithRetryOrFail(size, type, alignment); result->set_map_after_allocation(map, SKIP_WRITE_BARRIER); return result; } @@ -136,11 +143,11 @@ HeapObject Factory::AllocateRawWithAllocationSite( Handle<Map> map, PretenureFlag pretenure, Handle<AllocationSite> allocation_site) { DCHECK(map->instance_type() != MAP_TYPE); + AllocationType type = Heap::SelectType(Heap::SelectSpace(pretenure)); int size = map->instance_size(); if (!allocation_site.is_null()) size += AllocationMemento::kSize; AllocationSpace space = Heap::SelectSpace(pretenure); - HeapObject result = - isolate()->heap()->AllocateRawWithRetryOrFail(size, space); + HeapObject result = isolate()->heap()->AllocateRawWithRetryOrFail(size, type); WriteBarrierMode write_barrier_mode = space == NEW_SPACE ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; result->set_map_after_allocation(*map, write_barrier_mode); @@ -163,9 +170,8 @@ void Factory::InitializeAllocationMemento(AllocationMemento memento, } HeapObject Factory::AllocateRawArray(int size, PretenureFlag pretenure) { - AllocationSpace space = Heap::SelectSpace(pretenure); - HeapObject result = - isolate()->heap()->AllocateRawWithRetryOrFail(size, space); + AllocationType type = Heap::SelectType(Heap::SelectSpace(pretenure)); + HeapObject result = isolate()->heap()->AllocateRawWithRetryOrFail(size, type); if (size > kMaxRegularHeapObjectSize && FLAG_use_marking_progress_bar) { MemoryChunk* chunk = MemoryChunk::FromHeapObject(result); chunk->SetFlag<AccessMode::ATOMIC>(MemoryChunk::HAS_PROGRESS_BAR); @@ -191,12 +197,12 @@ HeapObject Factory::AllocateRawWeakArrayList(int capacity, HeapObject Factory::New(Handle<Map> map, PretenureFlag pretenure) { DCHECK(map->instance_type() != MAP_TYPE); int size = map->instance_size(); - AllocationSpace space = Heap::SelectSpace(pretenure); - HeapObject result = - isolate()->heap()->AllocateRawWithRetryOrFail(size, space); + AllocationType type = Heap::SelectType(Heap::SelectSpace(pretenure)); + HeapObject result = isolate()->heap()->AllocateRawWithRetryOrFail(size, type); // New space objects are allocated white. - WriteBarrierMode write_barrier_mode = - space == NEW_SPACE ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; + WriteBarrierMode write_barrier_mode = type == AllocationType::kYoung + ? SKIP_WRITE_BARRIER + : UPDATE_WRITE_BARRIER; result->set_map_after_allocation(*map, write_barrier_mode); return result; } @@ -205,7 +211,8 @@ Handle<HeapObject> Factory::NewFillerObject(int size, bool double_align, AllocationSpace space) { AllocationAlignment alignment = double_align ? kDoubleAligned : kWordAligned; Heap* heap = isolate()->heap(); - HeapObject result = heap->AllocateRawWithRetryOrFail(size, space, alignment); + HeapObject result = heap->AllocateRawWithRetryOrFail( + size, Heap::SelectType(space), alignment); #ifdef DEBUG MemoryChunk* chunk = MemoryChunk::FromHeapObject(result); DCHECK(chunk->owner()->identity() == space); @@ -375,8 +382,9 @@ MaybeHandle<FixedArray> Factory::TryNewFixedArray(int length, int size = FixedArray::SizeFor(length); AllocationSpace space = Heap::SelectSpace(pretenure); + AllocationType type = Heap::SelectType(space); Heap* heap = isolate()->heap(); - AllocationResult allocation = heap->AllocateRaw(size, space); + AllocationResult allocation = heap->AllocateRaw(size, type); HeapObject result; if (!allocation.To(&result)) return MaybeHandle<FixedArray>(); if (size > kMaxRegularHeapObjectSize && FLAG_use_marking_progress_bar) { @@ -605,12 +613,12 @@ Handle<AccessorPair> Factory::NewAccessorPair() { // Internalized strings are created in the old generation (data space). Handle<String> Factory::InternalizeUtf8String(Vector<const char> string) { - Utf8StringKey key(string, isolate()->heap()->HashSeed()); + Utf8StringKey key(string, HashSeed(isolate())); return InternalizeStringWithKey(&key); } Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) { - OneByteStringKey key(string, isolate()->heap()->HashSeed()); + OneByteStringKey key(string, HashSeed(isolate())); return InternalizeStringWithKey(&key); } @@ -621,7 +629,7 @@ Handle<String> Factory::InternalizeOneByteString( } Handle<String> Factory::InternalizeTwoByteString(Vector<const uc16> string) { - TwoByteStringKey key(string, isolate()->heap()->HashSeed()); + TwoByteStringKey key(string, HashSeed(isolate())); return InternalizeStringWithKey(&key); } @@ -661,13 +669,38 @@ MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string, return NewStringFromOneByte(Vector<const uint8_t>::cast(string), pretenure); } - // Non-ASCII and we need to decode. - auto non_ascii = string.SubVector(non_ascii_start, length); - Access<UnicodeCache::Utf8Decoder> decoder( - isolate()->unicode_cache()->utf8_decoder()); - decoder->Reset(non_ascii); + std::unique_ptr<uint16_t[]> buffer(new uint16_t[length - non_ascii_start]); + + const uint8_t* cursor = + reinterpret_cast<const uint8_t*>(&string[non_ascii_start]); + const uint8_t* end = reinterpret_cast<const uint8_t*>(string.end()); + + uint16_t* output_cursor = buffer.get(); + + uint32_t incomplete_char = 0; + unibrow::Utf8::State state = unibrow::Utf8::State::kAccept; - int utf16_length = static_cast<int>(decoder->Utf16Length()); + while (cursor < end) { + unibrow::uchar t = + unibrow::Utf8::ValueOfIncremental(&cursor, &state, &incomplete_char); + + if (V8_LIKELY(t <= unibrow::Utf16::kMaxNonSurrogateCharCode)) { + *(output_cursor++) = static_cast<uc16>(t); // The most frequent case. + } else if (t == unibrow::Utf8::kIncomplete) { + continue; + } else { + *(output_cursor++) = unibrow::Utf16::LeadSurrogate(t); + *(output_cursor++) = unibrow::Utf16::TrailSurrogate(t); + } + } + + unibrow::uchar t = unibrow::Utf8::ValueOfIncrementalFinish(&state); + if (t != unibrow::Utf8::kBufferEmpty) { + *(output_cursor++) = static_cast<uc16>(t); + } + + DCHECK_LE(output_cursor, buffer.get() + length - non_ascii_start); + int utf16_length = static_cast<int>(output_cursor - buffer.get()); DCHECK_GT(utf16_length, 0); // Allocate string. @@ -676,15 +709,13 @@ MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string, isolate(), result, NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), String); - // Copy ASCII portion. + DCHECK_LE(non_ascii_start + utf16_length, length); + DisallowHeapAllocation no_gc; uint16_t* data = result->GetChars(no_gc); - for (int i = 0; i < non_ascii_start; i++) { - *data++ = *ascii_data++; - } + CopyChars(data, ascii_data, non_ascii_start); + CopyChars(data + non_ascii_start, buffer.get(), utf16_length); - // Now write the remainder. - decoder->WriteUtf16(data, utf16_length, non_ascii); return result; } @@ -961,14 +992,10 @@ MaybeHandle<Map> GetInternalizedStringMap(Factory* f, Handle<String> string) { return f->external_internalized_string_map(); case EXTERNAL_ONE_BYTE_STRING_TYPE: return f->external_one_byte_internalized_string_map(); - case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: - return f->external_internalized_string_with_one_byte_data_map(); case UNCACHED_EXTERNAL_STRING_TYPE: return f->uncached_external_internalized_string_map(); case UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE: return f->uncached_external_one_byte_internalized_string_map(); - case UNCACHED_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: - return f->uncached_external_internalized_string_with_one_byte_data_map(); default: return MaybeHandle<Map>(); // No match found. } @@ -978,8 +1005,9 @@ MaybeHandle<Map> GetInternalizedStringMap(Factory* f, Handle<String> string) { MaybeHandle<Map> Factory::InternalizedStringMapForString( Handle<String> string) { - // If the string is in new space it cannot be used as internalized. - if (Heap::InNewSpace(*string)) return MaybeHandle<Map>(); + // If the string is in the young generation, it cannot be used as + // internalized. + if (Heap::InYoungGeneration(*string)) return MaybeHandle<Map>(); return GetInternalizedStringMap(this, string); } @@ -1145,17 +1173,6 @@ MaybeHandle<String> Factory::NewConsString(Handle<String> left, bool left_is_one_byte = left->IsOneByteRepresentation(); bool right_is_one_byte = right->IsOneByteRepresentation(); bool is_one_byte = left_is_one_byte && right_is_one_byte; - bool is_one_byte_data_in_two_byte_string = false; - if (!is_one_byte) { - // At least one of the strings uses two-byte representation so we - // can't use the fast case code for uncached one-byte strings below, but - // we can try to save memory if all chars actually fit in one-byte. - is_one_byte_data_in_two_byte_string = - left->HasOnlyOneByteChars() && right->HasOnlyOneByteChars(); - if (is_one_byte_data_in_two_byte_string) { - isolate()->counters()->string_add_runtime_ext_to_one_byte()->Increment(); - } - } // If the resulting string is small make a flat string. if (length < ConsString::kMinLength) { @@ -1184,16 +1201,11 @@ MaybeHandle<String> Factory::NewConsString(Handle<String> left, return result; } - return (is_one_byte_data_in_two_byte_string) - ? ConcatStringContent<uint8_t>( - NewRawOneByteString(length).ToHandleChecked(), left, right) - : ConcatStringContent<uc16>( - NewRawTwoByteString(length).ToHandleChecked(), left, - right); + return ConcatStringContent<uc16>( + NewRawTwoByteString(length).ToHandleChecked(), left, right); } - bool one_byte = (is_one_byte || is_one_byte_data_in_two_byte_string); - return NewConsString(left, right, length, one_byte); + return NewConsString(left, right, length, is_one_byte); } Handle<String> Factory::NewConsString(Handle<String> left, Handle<String> right, @@ -1308,12 +1320,9 @@ MaybeHandle<String> Factory::NewExternalStringFromOneByte( } if (length == 0) return empty_string(); - Handle<Map> map; - if (!resource->IsCacheable()) { - map = uncached_external_one_byte_string_map(); - } else { - map = external_one_byte_string_map(); - } + Handle<Map> map = resource->IsCacheable() + ? external_one_byte_string_map() + : uncached_external_one_byte_string_map(); Handle<ExternalOneByteString> external_string( ExternalOneByteString::cast(New(map, TENURED)), isolate()); external_string->set_length(static_cast<int>(length)); @@ -1332,20 +1341,8 @@ MaybeHandle<String> Factory::NewExternalStringFromTwoByte( } if (length == 0) return empty_string(); - // For small strings we check whether the resource contains only - // one byte characters. If yes, we use a different string map. - static const size_t kOneByteCheckLengthLimit = 32; - bool is_one_byte = - length <= kOneByteCheckLengthLimit && - String::IsOneByte(resource->data(), static_cast<int>(length)); - Handle<Map> map; - if (!resource->IsCacheable()) { - map = is_one_byte ? uncached_external_string_with_one_byte_data_map() - : uncached_external_string_map(); - } else { - map = is_one_byte ? external_string_with_one_byte_data_map() - : external_string_map(); - } + Handle<Map> map = resource->IsCacheable() ? external_string_map() + : uncached_external_string_map(); Handle<ExternalTwoByteString> external_string( ExternalTwoByteString::cast(New(map, TENURED)), isolate()); external_string->set_length(static_cast<int>(length)); @@ -1735,12 +1732,13 @@ Handle<PromiseResolveThenableJobTask> Factory::NewPromiseResolveThenableJobTask( return microtask; } -Handle<WeakFactoryCleanupJobTask> Factory::NewWeakFactoryCleanupJobTask( - Handle<JSWeakFactory> weak_factory) { - Handle<WeakFactoryCleanupJobTask> microtask = - Handle<WeakFactoryCleanupJobTask>::cast( - NewStruct(WEAK_FACTORY_CLEANUP_JOB_TASK_TYPE)); - microtask->set_factory(*weak_factory); +Handle<FinalizationGroupCleanupJobTask> +Factory::NewFinalizationGroupCleanupJobTask( + Handle<JSFinalizationGroup> finalization_group) { + Handle<FinalizationGroupCleanupJobTask> microtask = + Handle<FinalizationGroupCleanupJobTask>::cast( + NewStruct(FINALIZATION_GROUP_CLEANUP_JOB_TASK_TYPE)); + microtask->set_finalization_group(*finalization_group); return microtask; } @@ -1777,7 +1775,7 @@ Handle<BytecodeArray> Factory::NewBytecodeArray( isolate()->heap()->FatalProcessOutOfMemory("invalid array length"); } // Bytecode array is pretenured, so constant pool array should be too. - DCHECK(!Heap::InNewSpace(*constant_pool)); + DCHECK(!Heap::InYoungGeneration(*constant_pool)); int size = BytecodeArray::SizeFor(length); HeapObject result = @@ -1793,7 +1791,7 @@ Handle<BytecodeArray> Factory::NewBytecodeArray( instance->set_bytecode_age(BytecodeArray::kNoAgeBytecodeAge); instance->set_constant_pool(*constant_pool); instance->set_handler_table(*empty_byte_array()); - instance->set_source_position_table(*empty_byte_array()); + instance->set_source_position_table(*undefined_value()); CopyBytes(reinterpret_cast<byte*>(instance->GetFirstBytecodeAddress()), raw_bytecodes, length); instance->clear_padding(); @@ -1813,7 +1811,7 @@ Handle<FixedTypedArrayBase> Factory::NewFixedTypedArrayWithExternalPointer( Handle<FixedTypedArrayBase> elements(FixedTypedArrayBase::cast(result), isolate()); elements->set_base_pointer(Smi::kZero, SKIP_WRITE_BARRIER); - elements->set_external_pointer(external_pointer, SKIP_WRITE_BARRIER); + elements->set_external_pointer(external_pointer); elements->set_length(length); return elements; } @@ -1836,9 +1834,7 @@ Handle<FixedTypedArrayBase> Factory::NewFixedTypedArray( isolate()); elements->set_base_pointer(*elements, SKIP_WRITE_BARRIER); elements->set_external_pointer( - reinterpret_cast<void*>( - ExternalReference::fixed_typed_array_base_data_offset().address()), - SKIP_WRITE_BARRIER); + FixedTypedArrayBase::ExternalPointerPtrForOnHeapArray()); elements->set_length(static_cast<int>(length)); if (initialize) memset(elements->DataPtr(), 0, elements->DataSize()); return elements; @@ -1909,14 +1905,13 @@ Handle<PropertyCell> Factory::NewPropertyCell(Handle<Name> name, Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors, int slack, - PretenureFlag pretenure) { + AllocationType type) { + DCHECK(Heap::IsRegularObjectAllocation(type)); int number_of_all_descriptors = number_of_descriptors + slack; // Zero-length case must be handled outside. DCHECK_LT(0, number_of_all_descriptors); int size = DescriptorArray::SizeFor(number_of_all_descriptors); - DCHECK_LT(size, kMaxRegularHeapObjectSize); - AllocationSpace space = Heap::SelectSpace(pretenure); - HeapObject obj = isolate()->heap()->AllocateRawWithRetryOrFail(size, space); + HeapObject obj = isolate()->heap()->AllocateRawWithRetryOrFail(size, type); obj->set_map_after_allocation(*descriptor_array_map(), SKIP_WRITE_BARRIER); DescriptorArray array = DescriptorArray::cast(obj); array->Initialize(*empty_enum_cache(), *undefined_value(), @@ -1966,8 +1961,8 @@ Handle<Map> Factory::NewMap(InstanceType type, int instance_size, !Map::CanHaveFastTransitionableElementsKind(type), IsDictionaryElementsKind(elements_kind) || IsTerminalElementsKind(elements_kind)); - HeapObject result = - isolate()->heap()->AllocateRawWithRetryOrFail(Map::kSize, MAP_SPACE); + HeapObject result = isolate()->heap()->AllocateRawWithRetryOrFail( + Map::kSize, AllocationType::kMap); result->set_map_after_allocation(*meta_map(), SKIP_WRITE_BARRIER); return handle(InitializeMap(Map::cast(result), type, instance_size, elements_kind, inobject_properties), @@ -2010,6 +2005,7 @@ Map Factory::InitializeMap(Map map, InstanceType type, int instance_size, Map::OwnsDescriptorsBit::encode(true) | Map::ConstructionCounterBits::encode(Map::kNoSlackTracking); map->set_bit_field3(bit_field3); + map->clear_padding(); map->set_elements_kind(elements_kind); map->set_new_target_is_base(true); isolate()->counters()->maps_created()->Increment(); @@ -2044,9 +2040,9 @@ Handle<JSObject> Factory::CopyJSObjectWithAllocationSite( int adjusted_object_size = site.is_null() ? object_size : object_size + AllocationMemento::kSize; HeapObject raw_clone = isolate()->heap()->AllocateRawWithRetryOrFail( - adjusted_object_size, NEW_SPACE); + adjusted_object_size, AllocationType::kYoung); - SLOW_DCHECK(Heap::InNewSpace(raw_clone)); + DCHECK(Heap::InYoungGeneration(raw_clone)); // Since we know the clone is allocated in new space, we can copy // the contents without worrying about updating the write barrier. Heap::CopyBlock(raw_clone->address(), source->address(), object_size); @@ -2234,7 +2230,7 @@ Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) { Handle<FixedArray> Factory::CopyAndTenureFixedCOWArray( Handle<FixedArray> array) { - DCHECK(Heap::InNewSpace(*array)); + DCHECK(Heap::InYoungGeneration(*array)); Handle<FixedArray> result = CopyFixedArrayUpTo(array, array->length(), TENURED); @@ -2562,6 +2558,16 @@ Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) { return prototype; } +Handle<WeakCell> Factory::NewWeakCell() { + // Allocate the WeakCell object in the old space, because 1) WeakCell weakness + // handling is only implemented in the old space 2) they're supposedly + // long-living. TODO(marja, gsathya): Support WeakCells in Scavenger. + Handle<WeakCell> result(WeakCell::cast(AllocateRawWithImmortalMap( + WeakCell::kSize, TENURED, *weak_cell_map())), + isolate()); + return result; +} + Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( Handle<SharedFunctionInfo> info, Handle<Context> context, PretenureFlag pretenure) { @@ -2705,8 +2711,7 @@ MaybeHandle<Code> Factory::TryNewCode( const CodeDesc& desc, Code::Kind kind, Handle<Object> self_ref, int32_t builtin_index, MaybeHandle<ByteArray> maybe_source_position_table, MaybeHandle<DeoptimizationData> maybe_deopt_data, Movability movability, - bool is_turbofanned, int stack_slots, int safepoint_table_offset, - int handler_table_offset) { + bool is_turbofanned, int stack_slots) { // Allocate objects needed for code initialization. Handle<ByteArray> reloc_info = NewByteArray( desc.reloc_size, @@ -2726,7 +2731,7 @@ MaybeHandle<Code> Factory::TryNewCode( Heap* heap = isolate()->heap(); CodePageCollectionMemoryModificationScope code_allocation(heap); HeapObject result = - heap->AllocateRawWithLightRetry(object_size, CODE_SPACE); + heap->AllocateRawWithLightRetry(object_size, AllocationType::kCode); // Return an empty handle if we cannot allocate the code object. if (result.is_null()) return MaybeHandle<Code>(); @@ -2744,8 +2749,7 @@ MaybeHandle<Code> Factory::TryNewCode( InitializeCode(heap, code, object_size, desc, kind, self_ref, builtin_index, source_position_table, deopt_data, reloc_info, - data_container, is_turbofanned, stack_slots, - safepoint_table_offset, handler_table_offset); + data_container, is_turbofanned, stack_slots); // Flush the instruction cache before changing the permissions. // Note: we do this before setting permissions to ReadExecute because on @@ -2762,8 +2766,7 @@ Handle<Code> Factory::NewCode( const CodeDesc& desc, Code::Kind kind, Handle<Object> self_ref, int32_t builtin_index, MaybeHandle<ByteArray> maybe_source_position_table, MaybeHandle<DeoptimizationData> maybe_deopt_data, Movability movability, - bool is_turbofanned, int stack_slots, int safepoint_table_offset, - int handler_table_offset) { + bool is_turbofanned, int stack_slots) { // Allocate objects needed for code initialization. Handle<ByteArray> reloc_info = NewByteArray( desc.reloc_size, @@ -2784,7 +2787,7 @@ Handle<Code> Factory::NewCode( Heap* heap = isolate()->heap(); CodePageCollectionMemoryModificationScope code_allocation(heap); HeapObject result = - heap->AllocateRawWithRetryOrFail(object_size, CODE_SPACE); + heap->AllocateRawWithRetryOrFail(object_size, AllocationType::kCode); if (movability == kImmovable) { result = heap->EnsureImmovableCode(result, object_size); } @@ -2798,8 +2801,7 @@ Handle<Code> Factory::NewCode( InitializeCode(heap, code, object_size, desc, kind, self_ref, builtin_index, source_position_table, deopt_data, reloc_info, - data_container, is_turbofanned, stack_slots, - safepoint_table_offset, handler_table_offset); + data_container, is_turbofanned, stack_slots); // Flush the instruction cache before changing the permissions. // Note: we do this before setting permissions to ReadExecute because on @@ -2831,17 +2833,15 @@ Handle<Code> Factory::NewOffHeapTrampolineFor(Handle<Code> code, const bool set_is_off_heap_trampoline = true; const int stack_slots = code->has_safepoint_info() ? code->stack_slots() : 0; + result->code_data_container()->set_kind_specific_flags( + code->code_data_container()->kind_specific_flags()); result->initialize_flags(code->kind(), code->has_unwinding_info(), code->is_turbofanned(), stack_slots, set_is_off_heap_trampoline); result->set_builtin_index(code->builtin_index()); + result->set_safepoint_table_offset(code->safepoint_table_offset()); result->set_handler_table_offset(code->handler_table_offset()); - result->code_data_container()->set_kind_specific_flags( - code->code_data_container()->kind_specific_flags()); result->set_constant_pool_offset(code->constant_pool_offset()); - if (code->has_safepoint_info()) { - result->set_safepoint_table_offset(code->safepoint_table_offset()); - } result->set_code_comments_offset(code->code_comments_offset()); // Replace the newly generated trampoline's RelocInfo ByteArray with the @@ -2872,7 +2872,8 @@ Handle<Code> Factory::CopyCode(Handle<Code> code) { { int obj_size = code->Size(); CodePageCollectionMemoryModificationScope code_allocation(heap); - HeapObject result = heap->AllocateRawWithRetryOrFail(obj_size, CODE_SPACE); + HeapObject result = + heap->AllocateRawWithRetryOrFail(obj_size, AllocationType::kCode); // Copy code object. Address old_addr = code->address(); @@ -3468,8 +3469,7 @@ MaybeHandle<JSBoundFunction> Factory::NewJSBoundFunction( isolate(), prototype, JSReceiver::GetPrototype(isolate(), target_function), JSBoundFunction); - SaveContext save(isolate()); - isolate()->set_context(*target_function->GetCreationContext()); + SaveAndSwitchContext save(isolate(), *target_function->GetCreationContext()); // Create the [[BoundArguments]] for the result. Handle<FixedArray> bound_arguments; @@ -3658,7 +3658,8 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( } share->set_script_or_debug_info(*undefined_value(), SKIP_WRITE_BARRIER); #if V8_SFI_HAS_UNIQUE_ID - share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId()); + Handle<SharedFunctionInfoWithID>::cast(share)->set_unique_id( + isolate()->GetNextUniqueSharedFunctionInfoId()); #endif // Set integer fields (smi or int, depending on the architecture). @@ -3779,6 +3780,14 @@ Handle<String> Factory::NumberToString(Smi number, bool check_cache) { check_cache); } +Handle<ClassPositions> Factory::NewClassPositions(int start, int end) { + Handle<ClassPositions> class_positions = + Handle<ClassPositions>::cast(NewStruct(CLASS_POSITIONS_TYPE, TENURED)); + class_positions->set_start(start); + class_positions->set_end(end); + return class_positions; +} + Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { DCHECK(!shared->HasDebugInfo()); Heap* heap = isolate()->heap(); @@ -3834,6 +3843,20 @@ Handle<BreakPoint> Factory::NewBreakPoint(int id, Handle<String> condition) { return new_break_point; } +Handle<StackTraceFrame> Factory::NewStackTraceFrame( + Handle<FrameArray> frame_array, int index) { + Handle<StackTraceFrame> frame = Handle<StackTraceFrame>::cast( + NewStruct(STACK_TRACE_FRAME_TYPE, NOT_TENURED)); + frame->set_frame_array(*frame_array); + frame->set_frame_index(index); + frame->set_frame_info(*undefined_value()); + + int id = isolate()->last_stack_frame_info_id() + 1; + isolate()->set_last_stack_frame_info_id(id); + frame->set_id(id); + return frame; +} + Handle<StackFrameInfo> Factory::NewStackFrameInfo() { Handle<StackFrameInfo> stack_frame_info = Handle<StackFrameInfo>::cast( NewStruct(STACK_FRAME_INFO_TYPE, NOT_TENURED)); @@ -3847,6 +3870,51 @@ Handle<StackFrameInfo> Factory::NewStackFrameInfo() { return stack_frame_info; } +Handle<StackFrameInfo> Factory::NewStackFrameInfo( + Handle<FrameArray> frame_array, int index) { + FrameArrayIterator it(isolate(), frame_array, index); + DCHECK(it.HasFrame()); + + Handle<StackFrameInfo> info = Handle<StackFrameInfo>::cast( + NewStruct(STACK_FRAME_INFO_TYPE, NOT_TENURED)); + info->set_flag(0); + + const bool is_wasm = frame_array->IsAnyWasmFrame(index); + info->set_is_wasm(is_wasm); + + // Line numbers are 1-based, for Wasm we need to adjust. + int line = it.Frame()->GetLineNumber(); + if (is_wasm && line >= 0) line++; + info->set_line_number(line); + + // Column numbers are 1-based. For Wasm we use the position + // as the iterator does not currently provide a column number. + const int column = + is_wasm ? it.Frame()->GetPosition() + 1 : it.Frame()->GetColumnNumber(); + info->set_column_number(column); + + info->set_script_id(it.Frame()->GetScriptId()); + info->set_script_name(*it.Frame()->GetFileName()); + info->set_script_name_or_source_url(*it.Frame()->GetScriptNameOrSourceUrl()); + + // TODO(szuend): Adjust this, once it is decided what name to use in both + // "simple" and "detailed" stack traces. This code is for + // backwards compatibility to fullfill test expectations. + auto function_name = it.Frame()->GetFunctionName(); + if (!is_wasm) { + Handle<Object> function = it.Frame()->GetFunction(); + if (function->IsJSFunction()) { + function_name = + JSFunction::GetDebugName(Handle<JSFunction>::cast(function)); + } + } + info->set_function_name(*function_name); + info->set_is_eval(it.Frame()->IsEval()); + info->set_is_constructor(it.Frame()->IsConstructor()); + + return info; +} + Handle<SourcePositionTableWithFrameCache> Factory::NewSourcePositionTableWithFrameCache( Handle<ByteArray> source_position_table, @@ -3874,11 +3942,13 @@ Handle<JSObject> Factory::NewArgumentsObject(Handle<JSFunction> callee, Handle<JSObject> result = NewJSObjectFromMap(map); Handle<Smi> value(Smi::FromInt(length), isolate()); Object::SetProperty(isolate(), result, length_string(), value, - LanguageMode::kStrict) + StoreOrigin::kMaybeKeyed, + Just(ShouldThrow::kThrowOnError)) .Assert(); if (!strict_mode_callee) { Object::SetProperty(isolate(), result, callee_string(), callee, - LanguageMode::kStrict) + StoreOrigin::kMaybeKeyed, + Just(ShouldThrow::kThrowOnError)) .Assert(); } return result; |