���� JFIF �� � ( %"1"%)+...383,7(-.-
![]() Server : Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.4.20 System : Linux st2.domain.com 3.10.0-1127.10.1.el7.x86_64 #1 SMP Wed Jun 3 14:28:03 UTC 2020 x86_64 User : apache ( 48) PHP Version : 7.4.20 Disable Function : NONE Directory : /proc/self/root/home/real/node-v13.0.1/deps/v8/src/objects/ |
// Copyright 2017 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. #ifndef V8_OBJECTS_CODE_H_ #define V8_OBJECTS_CODE_H_ #include "src/codegen/handler-table.h" #include "src/objects/contexts.h" #include "src/objects/fixed-array.h" #include "src/objects/heap-object.h" #include "src/objects/objects.h" #include "src/objects/struct.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" namespace v8 { namespace internal { class ByteArray; class BytecodeArray; class CodeDataContainer; class CodeDesc; namespace interpreter { class Register; } // Code describes objects with on-the-fly generated machine code. class Code : public HeapObject { public: NEVER_READ_ONLY_SPACE // Opaque data type for encapsulating code flags like kind, inline // cache state, and arguments count. using Flags = uint32_t; #define CODE_KIND_LIST(V) \ V(OPTIMIZED_FUNCTION) \ V(BYTECODE_HANDLER) \ V(STUB) \ V(BUILTIN) \ V(REGEXP) \ V(WASM_FUNCTION) \ V(WASM_TO_CAPI_FUNCTION) \ V(WASM_TO_JS_FUNCTION) \ V(JS_TO_WASM_FUNCTION) \ V(JS_TO_JS_FUNCTION) \ V(WASM_INTERPRETER_ENTRY) \ V(C_WASM_ENTRY) enum Kind { #define DEFINE_CODE_KIND_ENUM(name) name, CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM) #undef DEFINE_CODE_KIND_ENUM NUMBER_OF_KINDS }; static const char* Kind2String(Kind kind); #ifdef ENABLE_DISASSEMBLER const char* GetName(Isolate* isolate) const; V8_EXPORT_PRIVATE void Disassemble(const char* name, std::ostream& os, Address current_pc = kNullAddress); #endif // [instruction_size]: Size of the native instructions, including embedded // data such as the safepoints table. inline int raw_instruction_size() const; inline void set_raw_instruction_size(int value); // Returns the size of the native instructions, including embedded // data such as the safepoints table. For off-heap code objects // this may differ from instruction_size in that this will return the size of // the off-heap instruction stream rather than the on-heap trampoline located // at instruction_start. inline int InstructionSize() const; V8_EXPORT_PRIVATE int OffHeapInstructionSize() const; // [relocation_info]: Code relocation information DECL_ACCESSORS(relocation_info, ByteArray) // This function should be called only from GC. void ClearEmbeddedObjects(Heap* heap); // [deoptimization_data]: Array containing data for deopt. DECL_ACCESSORS(deoptimization_data, FixedArray) // [source_position_table]: ByteArray for the source positions table or // SourcePositionTableWithFrameCache. DECL_ACCESSORS(source_position_table, Object) inline ByteArray SourcePositionTable() const; inline ByteArray SourcePositionTableIfCollected() const; // [code_data_container]: A container indirection for all mutable fields. DECL_ACCESSORS(code_data_container, CodeDataContainer) // [next_code_link]: Link for lists of optimized or deoptimized code. // Note that this field is stored in the {CodeDataContainer} to be mutable. inline Object next_code_link() const; inline void set_next_code_link(Object value); // Unchecked accessors to be used during GC. inline ByteArray unchecked_relocation_info() const; inline int relocation_size() const; // [kind]: Access to specific code kind. inline Kind kind() const; inline bool is_optimized_code() const; inline bool is_wasm_code() const; // Testers for interpreter builtins. inline bool is_interpreter_trampoline_builtin() const; // Tells whether the code checks the optimization marker in the function's // feedback vector. inline bool checks_optimization_marker() const; // Tells whether the outgoing parameters of this code are tagged pointers. inline bool has_tagged_params() const; // [is_turbofanned]: For kind STUB or OPTIMIZED_FUNCTION, tells whether the // code object was generated by the TurboFan optimizing compiler. inline bool is_turbofanned() const; // [can_have_weak_objects]: For kind OPTIMIZED_FUNCTION, tells whether the // embedded objects in code should be treated weakly. inline bool can_have_weak_objects() const; inline void set_can_have_weak_objects(bool value); // [builtin_index]: For builtins, tells which builtin index the code object // has. The builtin index is a non-negative integer for builtins, and -1 // otherwise. inline int builtin_index() const; inline void set_builtin_index(int id); inline bool is_builtin() const; inline bool has_safepoint_info() const; // [stack_slots]: If {has_safepoint_info()}, the number of stack slots // reserved in the code prologue. inline int stack_slots() const; // [safepoint_table_offset]: If {has_safepoint_info()}, the offset in the // instruction stream where the safepoint table starts. inline int safepoint_table_offset() const; inline void set_safepoint_table_offset(int offset); int safepoint_table_size() const; bool has_safepoint_table() const; // [handler_table_offset]: The offset in the instruction stream where the // exception handler table starts. inline int handler_table_offset() const; inline void set_handler_table_offset(int offset); int handler_table_size() const; bool has_handler_table() const; // [constant_pool offset]: Offset of the constant pool. // Valid for FLAG_enable_embedded_constant_pool only inline int constant_pool_offset() const; inline void set_constant_pool_offset(int offset); int constant_pool_size() const; bool has_constant_pool() const; // [code_comments_offset]: Offset of the code comment section. inline int code_comments_offset() const; inline void set_code_comments_offset(int offset); inline Address code_comments() const; V8_EXPORT_PRIVATE int code_comments_size() const; V8_EXPORT_PRIVATE bool has_code_comments() const; // The size of the executable instruction area, without embedded metadata. int ExecutableInstructionSize() const; // [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether // the code is going to be deoptimized. inline bool marked_for_deoptimization() const; inline void set_marked_for_deoptimization(bool flag); // [embedded_objects_cleared]: For kind OPTIMIZED_FUNCTION tells whether // the embedded objects in the code marked for deoptimization were cleared. // Note that embedded_objects_cleared() implies marked_for_deoptimization(). inline bool embedded_objects_cleared() const; inline void set_embedded_objects_cleared(bool flag); // [deopt_already_counted]: For kind OPTIMIZED_FUNCTION tells whether // the code was already deoptimized. inline bool deopt_already_counted() const; inline void set_deopt_already_counted(bool flag); // [is_promise_rejection]: For kind BUILTIN tells whether the // exception thrown by the code will lead to promise rejection or // uncaught if both this and is_exception_caught is set. // Use GetBuiltinCatchPrediction to access this. inline void set_is_promise_rejection(bool flag); // [is_exception_caught]: For kind BUILTIN tells whether the // exception thrown by the code will be caught internally or // uncaught if both this and is_promise_rejection is set. // Use GetBuiltinCatchPrediction to access this. inline void set_is_exception_caught(bool flag); // [is_off_heap_trampoline]: For kind BUILTIN tells whether // this is a trampoline to an off-heap builtin. inline bool is_off_heap_trampoline() const; // [constant_pool]: The constant pool for this function. inline Address constant_pool() const; // Get the safepoint entry for the given pc. SafepointEntry GetSafepointEntry(Address pc); // The entire code object including its header is copied verbatim to the // snapshot so that it can be written in one, fast, memcpy during // deserialization. The deserializer will overwrite some pointers, rather // like a runtime linker, but the random allocation addresses used in the // mksnapshot process would still be present in the unlinked snapshot data, // which would make snapshot production non-reproducible. This method wipes // out the to-be-overwritten header data for reproducible snapshots. inline void WipeOutHeader(); // Clear uninitialized padding space. This ensures that the snapshot content // is deterministic. Depending on the V8 build mode there could be no padding. inline void clear_padding(); // Initialize the flags field. Similar to clear_padding above this ensure that // the snapshot content is deterministic. inline void initialize_flags(Kind kind, bool has_unwinding_info, bool is_turbofanned, int stack_slots, bool is_off_heap_trampoline); // Convert a target address into a code object. static inline Code GetCodeFromTargetAddress(Address address); // Convert an entry address into an object. static inline Code GetObjectFromEntryAddress(Address location_of_address); // Returns the address of the first instruction. inline Address raw_instruction_start() const; // Returns the address of the first instruction. For off-heap code objects // this differs from instruction_start (which would point to the off-heap // trampoline instead). inline Address InstructionStart() const; V8_EXPORT_PRIVATE Address OffHeapInstructionStart() const; // Returns the address right after the last instruction. inline Address raw_instruction_end() const; // Returns the address right after the last instruction. For off-heap code // objects this differs from instruction_end (which would point to the // off-heap trampoline instead). inline Address InstructionEnd() const; V8_EXPORT_PRIVATE Address OffHeapInstructionEnd() const; // Returns the size of the instructions, padding, relocation and unwinding // information. inline int body_size() const; // Returns the size of code and its metadata. This includes the size of code // relocation information, deoptimization data and handler table. inline int SizeIncludingMetadata() const; // Returns the address of the first relocation info (read backwards!). inline byte* relocation_start() const; // Returns the address right after the relocation info (read backwards!). inline byte* relocation_end() const; // [has_unwinding_info]: Whether this code object has unwinding information. // If it doesn't, unwinding_information_start() will point to invalid data. // // The body of all code objects has the following layout. // // +--------------------------+ <-- raw_instruction_start() // | instructions | // | ... | // +--------------------------+ // | embedded metadata | <-- safepoint_table_offset() // | ... | <-- handler_table_offset() // | | <-- constant_pool_offset() // | | <-- code_comments_offset() // | | // +--------------------------+ <-- raw_instruction_end() // // If has_unwinding_info() is false, raw_instruction_end() points to the first // memory location after the end of the code object. Otherwise, the body // continues as follows: // // +--------------------------+ // | padding to the next | // | 8-byte aligned address | // +--------------------------+ <-- raw_instruction_end() // | [unwinding_info_size] | // | as uint64_t | // +--------------------------+ <-- unwinding_info_start() // | unwinding info | // | ... | // +--------------------------+ <-- unwinding_info_end() // // and unwinding_info_end() points to the first memory location after the end // of the code object. // inline bool has_unwinding_info() const; // [unwinding_info_size]: Size of the unwinding information. inline int unwinding_info_size() const; inline void set_unwinding_info_size(int value); // Returns the address of the unwinding information, if any. inline Address unwinding_info_start() const; // Returns the address right after the end of the unwinding information. inline Address unwinding_info_end() const; // Code entry point. inline Address entry() const; // Returns true if pc is inside this object's instructions. inline bool contains(Address pc); // Relocate the code by delta bytes. Called to signal that this code // object has been moved by delta bytes. void Relocate(intptr_t delta); // Migrate code from desc without flushing the instruction cache. void CopyFromNoFlush(Heap* heap, const CodeDesc& desc); // Copy the RelocInfo portion of |desc| to |dest|. The ByteArray must be // exactly the same size as the RelocInfo in |desc|. static inline void CopyRelocInfoToByteArray(ByteArray dest, const CodeDesc& desc); // Flushes the instruction cache for the executable instructions of this code // object. Make sure to call this while the code is still writable. void FlushICache() const; // Returns the object size for a given body (used for allocation). static int SizeFor(int body_size) { DCHECK_SIZE_TAG_ALIGNED(body_size); return RoundUp(kHeaderSize + body_size, kCodeAlignment); } // Calculate the size of the code object to report for log events. This takes // the layout of the code object into account. inline int ExecutableSize() const; DECL_CAST(Code) // Dispatched behavior. inline int CodeSize() const; DECL_PRINTER(Code) DECL_VERIFIER(Code) void PrintDeoptLocation(FILE* out, const char* str, Address pc); bool CanDeoptAt(Address pc); void SetMarkedForDeoptimization(const char* reason); inline HandlerTable::CatchPrediction GetBuiltinCatchPrediction(); bool IsIsolateIndependent(Isolate* isolate); inline bool CanContainWeakObjects(); inline bool IsWeakObject(HeapObject object); static inline bool IsWeakObjectInOptimizedCode(HeapObject object); // Return true if the function is inlined in the code. bool Inlines(SharedFunctionInfo sfi); class OptimizedCodeIterator; // Layout description. #define CODE_FIELDS(V) \ V(kRelocationInfoOffset, kTaggedSize) \ V(kDeoptimizationDataOffset, kTaggedSize) \ V(kSourcePositionTableOffset, kTaggedSize) \ V(kCodeDataContainerOffset, kTaggedSize) \ /* Data or code not directly visited by GC directly starts here. */ \ /* The serializer needs to copy bytes starting from here verbatim. */ \ /* Objects embedded into code is visited via reloc info. */ \ V(kDataStart, 0) \ V(kInstructionSizeOffset, kIntSize) \ V(kFlagsOffset, kIntSize) \ V(kSafepointTableOffsetOffset, kIntSize) \ V(kHandlerTableOffsetOffset, kIntSize) \ V(kConstantPoolOffsetOffset, \ FLAG_enable_embedded_constant_pool ? kIntSize : 0) \ V(kCodeCommentsOffsetOffset, kIntSize) \ V(kBuiltinIndexOffset, kIntSize) \ V(kUnalignedHeaderSize, 0) \ /* Add padding to align the instruction start following right after */ \ /* the Code object header. */ \ V(kOptionalPaddingOffset, CODE_POINTER_PADDING(kOptionalPaddingOffset)) \ V(kHeaderSize, 0) DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, CODE_FIELDS) #undef CODE_FIELDS // This documents the amount of free space we have in each Code object header // due to padding for code alignment. #if V8_TARGET_ARCH_ARM64 static constexpr int kHeaderPaddingSize = COMPRESS_POINTERS_BOOL ? 20 : 0; #elif V8_TARGET_ARCH_MIPS64 static constexpr int kHeaderPaddingSize = 0; #elif V8_TARGET_ARCH_X64 static constexpr int kHeaderPaddingSize = COMPRESS_POINTERS_BOOL ? 20 : 0; #elif V8_TARGET_ARCH_ARM static constexpr int kHeaderPaddingSize = 20; #elif V8_TARGET_ARCH_IA32 static constexpr int kHeaderPaddingSize = 20; #elif V8_TARGET_ARCH_MIPS static constexpr int kHeaderPaddingSize = 20; #elif V8_TARGET_ARCH_PPC64 static constexpr int kHeaderPaddingSize = FLAG_enable_embedded_constant_pool ? 28 : 0; #elif V8_TARGET_ARCH_S390X static constexpr int kHeaderPaddingSize = 0; #else #error Unknown architecture. #endif STATIC_ASSERT(FIELD_SIZE(kOptionalPaddingOffset) == kHeaderPaddingSize); inline int GetUnwindingInfoSizeOffset() const; class BodyDescriptor; // Flags layout. BitField<type, shift, size>. #define CODE_FLAGS_BIT_FIELDS(V, _) \ V(HasUnwindingInfoField, bool, 1, _) \ V(KindField, Kind, 5, _) \ V(IsTurbofannedField, bool, 1, _) \ V(StackSlotsField, int, 24, _) \ V(IsOffHeapTrampoline, bool, 1, _) DEFINE_BIT_FIELDS(CODE_FLAGS_BIT_FIELDS) #undef CODE_FLAGS_BIT_FIELDS static_assert(NUMBER_OF_KINDS <= KindField::kMax, "Code::KindField size"); static_assert(IsOffHeapTrampoline::kLastUsedBit < 32, "Code::flags field exhausted"); // KindSpecificFlags layout (STUB, BUILTIN and OPTIMIZED_FUNCTION) #define CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS(V, _) \ V(MarkedForDeoptimizationField, bool, 1, _) \ V(EmbeddedObjectsClearedField, bool, 1, _) \ V(DeoptAlreadyCountedField, bool, 1, _) \ V(CanHaveWeakObjectsField, bool, 1, _) \ V(IsPromiseRejectionField, bool, 1, _) \ V(IsExceptionCaughtField, bool, 1, _) DEFINE_BIT_FIELDS(CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS) #undef CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS static_assert(IsExceptionCaughtField::kLastUsedBit < 32, "KindSpecificFlags full"); // The {marked_for_deoptimization} field is accessed from generated code. static const int kMarkedForDeoptimizationBit = MarkedForDeoptimizationField::kShift; static const int kArgumentsBits = 16; // Reserve one argument count value as the "don't adapt arguments" sentinel. static const int kMaxArguments = (1 << kArgumentsBits) - 2; private: friend class RelocIterator; bool is_promise_rejection() const; bool is_exception_caught() const; OBJECT_CONSTRUCTORS(Code, HeapObject); }; class Code::OptimizedCodeIterator { public: explicit OptimizedCodeIterator(Isolate* isolate); Code Next(); private: NativeContext next_context_; Code current_code_; Isolate* isolate_; DISALLOW_HEAP_ALLOCATION(no_gc) DISALLOW_COPY_AND_ASSIGN(OptimizedCodeIterator); }; // CodeDataContainer is a container for all mutable fields associated with its // referencing {Code} object. Since {Code} objects reside on write-protected // pages within the heap, its header fields need to be immutable. There always // is a 1-to-1 relation between {Code} and {CodeDataContainer}, the referencing // field {Code::code_data_container} itself is immutable. class CodeDataContainer : public HeapObject { public: NEVER_READ_ONLY_SPACE DECL_ACCESSORS(next_code_link, Object) DECL_INT_ACCESSORS(kind_specific_flags) // Clear uninitialized padding space. This ensures that the snapshot content // is deterministic. inline void clear_padding(); DECL_CAST(CodeDataContainer) // Dispatched behavior. DECL_PRINTER(CodeDataContainer) DECL_VERIFIER(CodeDataContainer) // Layout description. #define CODE_DATA_FIELDS(V) \ /* Weak pointer fields. */ \ V(kPointerFieldsStrongEndOffset, 0) \ V(kNextCodeLinkOffset, kTaggedSize) \ V(kPointerFieldsWeakEndOffset, 0) \ /* Raw data fields. */ \ V(kKindSpecificFlagsOffset, kIntSize) \ V(kUnalignedSize, OBJECT_POINTER_PADDING(kUnalignedSize)) \ /* Total size. */ \ V(kSize, 0) DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, CODE_DATA_FIELDS) #undef CODE_DATA_FIELDS class BodyDescriptor; OBJECT_CONSTRUCTORS(CodeDataContainer, HeapObject); }; class AbstractCode : public HeapObject { public: NEVER_READ_ONLY_SPACE // All code kinds and INTERPRETED_FUNCTION. enum Kind { #define DEFINE_CODE_KIND_ENUM(name) name, CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM) #undef DEFINE_CODE_KIND_ENUM INTERPRETED_FUNCTION, NUMBER_OF_KINDS }; static const char* Kind2String(Kind kind); int SourcePosition(int offset); int SourceStatementPosition(int offset); // Returns the address of the first instruction. inline Address raw_instruction_start(); // Returns the address of the first instruction. For off-heap code objects // this differs from instruction_start (which would point to the off-heap // trampoline instead). inline Address InstructionStart(); // Returns the address right after the last instruction. inline Address raw_instruction_end(); // Returns the address right after the last instruction. For off-heap code // objects this differs from instruction_end (which would point to the // off-heap trampoline instead). inline Address InstructionEnd(); // Returns the size of the code instructions. inline int raw_instruction_size(); // Returns the size of the native instructions, including embedded // data such as the safepoints table. For off-heap code objects // this may differ from instruction_size in that this will return the size of // the off-heap instruction stream rather than the on-heap trampoline located // at instruction_start. inline int InstructionSize(); // Return the source position table. inline ByteArray source_position_table(); inline Object stack_frame_cache(); static void SetStackFrameCache(Handle<AbstractCode> abstract_code, Handle<SimpleNumberDictionary> cache); void DropStackFrameCache(); // Returns the size of instructions and the metadata. inline int SizeIncludingMetadata(); // Returns true if pc is inside this object's instructions. inline bool contains(Address pc); // Returns the AbstractCode::Kind of the code. inline Kind kind(); // Calculate the size of the code object to report for log events. This takes // the layout of the code object into account. inline int ExecutableSize(); DECL_CAST(AbstractCode) inline Code GetCode(); inline BytecodeArray GetBytecodeArray(); // Max loop nesting marker used to postpose OSR. We don't take loop // nesting that is deeper than 5 levels into account. static const int kMaxLoopNestingMarker = 6; OBJECT_CONSTRUCTORS(AbstractCode, HeapObject); }; // Dependent code is a singly linked list of weak fixed arrays. Each array // contains weak pointers to code objects for one dependent group. The suffix of // the array can be filled with the undefined value if the number of codes is // less than the length of the array. // // +------+-----------------+--------+--------+-----+--------+-----------+-----+ // | next | count & group 1 | code 1 | code 2 | ... | code n | undefined | ... | // +------+-----------------+--------+--------+-----+--------+-----------+-----+ // | // V // +------+-----------------+--------+--------+-----+--------+-----------+-----+ // | next | count & group 2 | code 1 | code 2 | ... | code m | undefined | ... | // +------+-----------------+--------+--------+-----+--------+-----------+-----+ // | // V // empty_weak_fixed_array() // // The list of weak fixed arrays is ordered by dependency groups. class DependentCode : public WeakFixedArray { public: DECL_CAST(DependentCode) enum DependencyGroup { // Group of code that embed a transition to this map, and depend on being // deoptimized when the transition is replaced by a new version. kTransitionGroup, // Group of code that omit run-time prototype checks for prototypes // described by this map. The group is deoptimized whenever an object // described by this map changes shape (and transitions to a new map), // possibly invalidating the assumptions embedded in the code. kPrototypeCheckGroup, // Group of code that depends on global property values in property cells // not being changed. kPropertyCellChangedGroup, // Group of code that omit run-time checks for field(s) introduced by // this map, i.e. for the field type. kFieldOwnerGroup, // Group of code that omit run-time type checks for initial maps of // constructors. kInitialMapChangedGroup, // Group of code that depends on tenuring information in AllocationSites // not being changed. kAllocationSiteTenuringChangedGroup, // Group of code that depends on element transition information in // AllocationSites not being changed. kAllocationSiteTransitionChangedGroup }; // Register a code dependency of {cell} on {object}. V8_EXPORT_PRIVATE static void InstallDependency(Isolate* isolate, const MaybeObjectHandle& code, Handle<HeapObject> object, DependencyGroup group); void DeoptimizeDependentCodeGroup(Isolate* isolate, DependencyGroup group); bool MarkCodeForDeoptimization(Isolate* isolate, DependencyGroup group); // The following low-level accessors are exposed only for tests. inline DependencyGroup group(); inline MaybeObject object_at(int i); inline int count(); inline DependentCode next_link(); private: static const char* DependencyGroupName(DependencyGroup group); // Get/Set {object}'s {DependentCode}. static DependentCode GetDependentCode(Handle<HeapObject> object); static void SetDependentCode(Handle<HeapObject> object, Handle<DependentCode> dep); static Handle<DependentCode> New(Isolate* isolate, DependencyGroup group, const MaybeObjectHandle& object, Handle<DependentCode> next); static Handle<DependentCode> EnsureSpace(Isolate* isolate, Handle<DependentCode> entries); static Handle<DependentCode> InsertWeakCode(Isolate* isolate, Handle<DependentCode> entries, DependencyGroup group, const MaybeObjectHandle& code); // Compact by removing cleared weak cells and return true if there was // any cleared weak cell. bool Compact(); static int Grow(int number_of_entries) { if (number_of_entries < 5) return number_of_entries + 1; return number_of_entries * 5 / 4; } static const int kGroupCount = kAllocationSiteTransitionChangedGroup + 1; static const int kNextLinkIndex = 0; static const int kFlagsIndex = 1; static const int kCodesStartIndex = 2; inline void set_next_link(DependentCode next); inline void set_count(int value); inline void set_object_at(int i, MaybeObject object); inline void clear_at(int i); inline void copy(int from, int to); inline int flags(); inline void set_flags(int flags); using GroupField = BitField<int, 0, 3>; using CountField = BitField<int, 3, 27>; STATIC_ASSERT(kGroupCount <= GroupField::kMax + 1); OBJECT_CONSTRUCTORS(DependentCode, WeakFixedArray); }; // BytecodeArray represents a sequence of interpreter bytecodes. class BytecodeArray : public FixedArrayBase { public: enum Age { kNoAgeBytecodeAge = 0, kQuadragenarianBytecodeAge, kQuinquagenarianBytecodeAge, kSexagenarianBytecodeAge, kSeptuagenarianBytecodeAge, kOctogenarianBytecodeAge, kAfterLastBytecodeAge, kFirstBytecodeAge = kNoAgeBytecodeAge, kLastBytecodeAge = kAfterLastBytecodeAge - 1, kBytecodeAgeCount = kAfterLastBytecodeAge - kFirstBytecodeAge - 1, kIsOldBytecodeAge = kSexagenarianBytecodeAge }; static constexpr int SizeFor(int length) { return OBJECT_POINTER_ALIGN(kHeaderSize + length); } // Setter and getter inline byte get(int index) const; inline void set(int index, byte value); // Returns data start address. inline Address GetFirstBytecodeAddress(); // Accessors for frame size. inline int32_t frame_size() const; inline void set_frame_size(int32_t frame_size); // Accessor for register count (derived from frame_size). inline int register_count() const; // Accessors for parameter count (including implicit 'this' receiver). inline int32_t parameter_count() const; inline void set_parameter_count(int32_t number_of_parameters); // Register used to pass the incoming new.target or generator object from the // fucntion call. inline interpreter::Register incoming_new_target_or_generator_register() const; inline void set_incoming_new_target_or_generator_register( interpreter::Register incoming_new_target_or_generator_register); // Accessors for OSR loop nesting level. inline int osr_loop_nesting_level() const; inline void set_osr_loop_nesting_level(int depth); // Accessors for bytecode's code age. inline Age bytecode_age() const; inline void set_bytecode_age(Age age); // Accessors for the constant pool. DECL_ACCESSORS(constant_pool, FixedArray) // Accessors for handler table containing offsets of exception handlers. DECL_ACCESSORS(handler_table, ByteArray) // Accessors for source position table. Can contain: // * undefined (initial value) // * empty_byte_array (for bytecode generated for functions that will never // have source positions, e.g. native functions). // * ByteArray (when source positions have been collected for the bytecode) // * SourcePositionTableWithFrameCache (as above but with a frame cache) // * exception (when an error occurred while explicitly collecting source // positions for pre-existing bytecode). DECL_ACCESSORS(source_position_table, Object) // This must only be called if source position collection has already been // attempted. (If it failed because of an exception then it will return // empty_byte_array). inline ByteArray SourcePositionTable() const; // If source positions have not been collected or an exception has been thrown // this will return empty_byte_array. inline ByteArray SourcePositionTableIfCollected() const; inline bool HasSourcePositionTable() const; inline bool DidSourcePositionGenerationFail() const; inline void ClearFrameCacheFromSourcePositionTable(); // Indicates that an attempt was made to collect source positions, but that it // failed most likely due to stack exhaustion. When in this state // |SourcePositionTable| will return an empty byte array rather than crashing // as it would if no attempt was ever made to collect source positions. inline void SetSourcePositionsFailedToCollect(); DECL_CAST(BytecodeArray) // Dispatched behavior. inline int BytecodeArraySize(); inline int raw_instruction_size(); // Returns the size of bytecode and its metadata. This includes the size of // bytecode, constant pool, source position table, and handler table. inline int SizeIncludingMetadata(); DECL_PRINTER(BytecodeArray) DECL_VERIFIER(BytecodeArray) V8_EXPORT_PRIVATE void Disassemble(std::ostream& os); void CopyBytecodesTo(BytecodeArray to); // Bytecode aging V8_EXPORT_PRIVATE bool IsOld() const; V8_EXPORT_PRIVATE void MakeOlder(); // Clear uninitialized padding space. This ensures that the snapshot content // is deterministic. inline void clear_padding(); // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(FixedArrayBase::kHeaderSize, TORQUE_GENERATED_BYTECODE_ARRAY_FIELDS) static constexpr int kHeaderSize = kSize; // InterpreterEntryTrampoline expects these fields to be next to each other // and writes a 16-bit value to reset them. STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset == kOsrNestingLevelOffset + kCharSize); // Maximal memory consumption for a single BytecodeArray. static const int kMaxSize = 512 * MB; // Maximal length of a single BytecodeArray. static const int kMaxLength = kMaxSize - kHeaderSize; class BodyDescriptor; OBJECT_CONSTRUCTORS(BytecodeArray, FixedArrayBase); }; // DeoptimizationData is a fixed array used to hold the deoptimization data for // optimized code. It also contains information about functions that were // inlined. If N different functions were inlined then the first N elements of // the literal array will contain these functions. // // It can be empty. class DeoptimizationData : public FixedArray { public: // Layout description. Indices in the array. static const int kTranslationByteArrayIndex = 0; static const int kInlinedFunctionCountIndex = 1; static const int kLiteralArrayIndex = 2; static const int kOsrBytecodeOffsetIndex = 3; static const int kOsrPcOffsetIndex = 4; static const int kOptimizationIdIndex = 5; static const int kSharedFunctionInfoIndex = 6; static const int kInliningPositionsIndex = 7; static const int kDeoptExitStartIndex = 8; static const int kFirstDeoptEntryIndex = 9; // Offsets of deopt entry elements relative to the start of the entry. static const int kBytecodeOffsetRawOffset = 0; static const int kTranslationIndexOffset = 1; static const int kPcOffset = 2; static const int kDeoptEntrySize = 3; // Simple element accessors. #define DECL_ELEMENT_ACCESSORS(name, type) \ inline type name() const; \ inline void Set##name(type value); DECL_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray) DECL_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi) DECL_ELEMENT_ACCESSORS(LiteralArray, FixedArray) DECL_ELEMENT_ACCESSORS(OsrBytecodeOffset, Smi) DECL_ELEMENT_ACCESSORS(OsrPcOffset, Smi) DECL_ELEMENT_ACCESSORS(OptimizationId, Smi) DECL_ELEMENT_ACCESSORS(SharedFunctionInfo, Object) DECL_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>) DECL_ELEMENT_ACCESSORS(DeoptExitStart, Smi) #undef DECL_ELEMENT_ACCESSORS // Accessors for elements of the ith deoptimization entry. #define DECL_ENTRY_ACCESSORS(name, type) \ inline type name(int i) const; \ inline void Set##name(int i, type value); DECL_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi) DECL_ENTRY_ACCESSORS(TranslationIndex, Smi) DECL_ENTRY_ACCESSORS(Pc, Smi) #undef DECL_ENTRY_ACCESSORS inline BailoutId BytecodeOffset(int i); inline void SetBytecodeOffset(int i, BailoutId value); inline int DeoptCount(); static const int kNotInlinedIndex = -1; // Returns the inlined function at the given position in LiteralArray, or the // outer function if index == kNotInlinedIndex. class SharedFunctionInfo GetInlinedFunction(int index); // Allocates a DeoptimizationData. static Handle<DeoptimizationData> New(Isolate* isolate, int deopt_entry_count, AllocationType allocation); // Return an empty DeoptimizationData. V8_EXPORT_PRIVATE static Handle<DeoptimizationData> Empty(Isolate* isolate); DECL_CAST(DeoptimizationData) #ifdef ENABLE_DISASSEMBLER void DeoptimizationDataPrint(std::ostream& os); // NOLINT #endif private: static int IndexForEntry(int i) { return kFirstDeoptEntryIndex + (i * kDeoptEntrySize); } static int LengthFor(int entry_count) { return IndexForEntry(entry_count); } OBJECT_CONSTRUCTORS(DeoptimizationData, FixedArray); }; class SourcePositionTableWithFrameCache : public TorqueGeneratedSourcePositionTableWithFrameCache< SourcePositionTableWithFrameCache, Struct> { public: TQ_OBJECT_CONSTRUCTORS(SourcePositionTableWithFrameCache) }; } // namespace internal } // namespace v8 #include "src/objects/object-macros-undef.h" #endif // V8_OBJECTS_CODE_H_