Commit c02a9fb1 authored by ishell@chromium.org's avatar ishell@chromium.org Committed by V8 LUCI CQ

[ext-code-space] Allow AbstractCode to be CodeDataContainer

... when external code space is enabled.
Currently this mode is guarded by V8_REMOVE_BUILTINS_CODE_OBJECTS flag
which is set to false until Code-less builtins are supported.

Drive-by:
* remove unnecessary methods from AbstractCode,
* avoid CodeDataContainer <-> Code roundtrips when accessing writable
  state of Code objects via CodeT.

Bug: v8:11880
Change-Id: Iae3ff3b2feae68d875cbe9f82a6bb076460dd2f8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3769832
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81814}
parent ff0432c8
......@@ -145,10 +145,15 @@ const size_t kShortBuiltinCallsOldSpaceSizeThreshold = size_t{2} * GB;
#ifdef V8_EXTERNAL_CODE_SPACE
#define V8_EXTERNAL_CODE_SPACE_BOOL true
// This flag enables the mode when V8 does not create trampoline Code objects
// for builtins. It should be enough to have only CodeDataContainer objects.
// TODO(v8:11880): remove the flag one the Code-less builtins mode works.
#define V8_REMOVE_BUILTINS_CODE_OBJECTS false
class CodeDataContainer;
using CodeT = CodeDataContainer;
#else
#define V8_EXTERNAL_CODE_SPACE_BOOL false
#define V8_REMOVE_BUILTINS_CODE_OBJECTS false
class Code;
using CodeT = Code;
#endif
......
This diff is collapsed.
......@@ -250,8 +250,7 @@ Address CodeDataContainer::OffHeapInstructionStart(Isolate* isolate,
Address Code::OffHeapInstructionEnd(Isolate* isolate, Address pc) const {
DCHECK(is_off_heap_trampoline());
EmbeddedData d = EmbeddedData::GetEmbeddedDataForPC(isolate, pc);
return d.InstructionStartOfBuiltin(builtin_id()) +
d.InstructionSizeOfBuiltin(builtin_id());
return d.InstructionEndOf(builtin_id());
}
#ifdef V8_EXTERNAL_CODE_SPACE
......@@ -259,10 +258,24 @@ Address CodeDataContainer::OffHeapInstructionEnd(Isolate* isolate,
Address pc) const {
DCHECK(is_off_heap_trampoline());
EmbeddedData d = EmbeddedData::GetEmbeddedDataForPC(isolate, pc);
return d.InstructionStartOfBuiltin(builtin_id()) +
d.InstructionSizeOfBuiltin(builtin_id());
return d.InstructionEndOf(builtin_id());
}
#endif
#endif // V8_EXTERNAL_CODE_SPACE
bool Code::OffHeapBuiltinContains(Isolate* isolate, Address pc) const {
DCHECK(is_off_heap_trampoline());
EmbeddedData d = EmbeddedData::GetEmbeddedDataForPC(isolate, pc);
return d.BuiltinContains(builtin_id(), pc);
}
#ifdef V8_EXTERNAL_CODE_SPACE
bool CodeDataContainer::OffHeapBuiltinContains(Isolate* isolate,
Address pc) const {
DCHECK(is_off_heap_trampoline());
EmbeddedData d = EmbeddedData::GetEmbeddedDataForPC(isolate, pc);
return d.BuiltinContains(builtin_id(), pc);
}
#endif // V8_EXTERNAL_CODE_SPACE
// TODO(cbruni): Move to BytecodeArray
int AbstractCode::SourcePosition(PtrComprCageBase cage_base, int offset) {
......
......@@ -60,11 +60,11 @@ class CodeDataContainer : public HeapObject {
// writable state of the respective Code object.
//
inline bool can_have_weak_objects() const;
inline void set_can_have_weak_objects(bool value);
DECL_PRIMITIVE_ACCESSORS(can_have_weak_objects, bool)
DECL_PRIMITIVE_ACCESSORS(marked_for_deoptimization, bool)
DECL_PRIMITIVE_ACCESSORS(is_promise_rejection, bool)
inline bool marked_for_deoptimization() const;
inline void set_marked_for_deoptimization(bool flag);
inline HandlerTable::CatchPrediction GetBuiltinCatchPrediction() const;
// Back-reference to the Code object.
// Available only when V8_EXTERNAL_CODE_SPACE is defined.
......@@ -165,6 +165,9 @@ class CodeDataContainer : public HeapObject {
DECL_GETTER(source_position_table, ByteArray)
DECL_GETTER(bytecode_offset_table, ByteArray)
// Returns true if pc is inside this object's instructions.
inline bool contains(Isolate* isolate, Address pc);
inline Address SafepointTableAddress() const;
inline int safepoint_table_size() const;
inline bool has_safepoint_table() const;
......@@ -190,10 +193,14 @@ class CodeDataContainer : public HeapObject {
// TODO(11527): remove these versions once the full solution is ready.
Address OffHeapInstructionStart(Isolate* isolate, Address pc) const;
Address OffHeapInstructionEnd(Isolate* isolate, Address pc) const;
bool OffHeapBuiltinContains(Isolate* isolate, Address pc) const;
inline Address InstructionStart(Isolate* isolate, Address pc) const;
inline Address InstructionEnd(Isolate* isolate, Address pc) const;
inline Address InstructionEnd() const;
inline int InstructionSize() const;
#endif // V8_EXTERNAL_CODE_SPACE
DECL_CAST(CodeDataContainer)
......@@ -353,6 +360,9 @@ class Code : public HeapObject {
V8_EXPORT_PRIVATE Address OffHeapInstructionEnd(Isolate* isolate,
Address pc) const;
V8_EXPORT_PRIVATE bool OffHeapBuiltinContains(Isolate* isolate,
Address pc) const;
// Computes offset of the |pc| from the instruction start. The |pc| must
// belong to this code.
inline int GetOffsetFromInstructionStart(Isolate* isolate, Address pc) const;
......@@ -638,7 +648,7 @@ class Code : public HeapObject {
void SetMarkedForDeoptimization(const char* reason);
inline HandlerTable::CatchPrediction GetBuiltinCatchPrediction();
inline HandlerTable::CatchPrediction GetBuiltinCatchPrediction() const;
bool IsIsolateIndependent(Isolate* isolate);
......@@ -944,6 +954,12 @@ inline Code FromCodeT(CodeT code, PtrComprCageBase, AcquireLoadTag);
inline Handle<CodeT> FromCodeT(Handle<Code> code, Isolate* isolate);
inline CodeDataContainer CodeDataContainerFromCodeT(CodeT code);
// AbsractCode is an helper wrapper around {Code | BytecodeArray} or
// {Code | CodeDataContainer | BytecodeArray} depending on whether the
// V8_REMOVE_BUILTINS_CODE_OBJECTS is disabled or not.
// Note that when V8_EXTERNAL_CODE_SPACE is enabled then the same abstract code
// can be represented either by Code object or by respective CodeDataContainer
// object.
class AbstractCode : public HeapObject {
public:
NEVER_READ_ONLY_SPACE
......@@ -951,25 +967,16 @@ class AbstractCode : public HeapObject {
int SourcePosition(PtrComprCageBase cage_base, int offset);
int SourceStatementPosition(PtrComprCageBase cage_base, int offset);
// Returns the address of the first instruction.
inline Address raw_instruction_start(PtrComprCageBase cage_base);
// 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(PtrComprCageBase cage_base);
// Returns the address right after the last instruction.
inline Address raw_instruction_end(PtrComprCageBase cage_base);
// 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(PtrComprCageBase cage_base);
// Returns the size of the code instructions.
inline int raw_instruction_size(PtrComprCageBase cage_base);
// 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
......@@ -992,12 +999,27 @@ class AbstractCode : public HeapObject {
// Returns the kind of the code.
inline CodeKind kind(PtrComprCageBase cage_base);
inline Builtin builtin_id(PtrComprCageBase cage_base);
inline bool is_interpreter_trampoline_builtin(PtrComprCageBase cage_base);
inline HandlerTable::CatchPrediction GetBuiltinCatchPrediction(
PtrComprCageBase cage_base);
DECL_CAST(AbstractCode)
// The following predicates don't have the parameterless versions on
// purpose - in order to avoid the expensive cage base computation that
// should work for both regular V8 heap objects and external code space
// objects.
inline bool IsCode(PtrComprCageBase cage_base) const;
inline Code GetCode();
inline bool IsCodeT(PtrComprCageBase cage_base) const;
inline bool IsBytecodeArray(PtrComprCageBase cage_base) const;
inline CodeT ToCodeT(PtrComprCageBase cage_base);
inline Code GetCode();
inline CodeT GetCodeT();
inline BytecodeArray GetBytecodeArray();
OBJECT_CONSTRUCTORS(AbstractCode, HeapObject);
......
......@@ -10,6 +10,17 @@
namespace v8 {
namespace internal {
bool EmbeddedData::BuiltinContains(Builtin builtin, Address pc) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
Address start =
reinterpret_cast<Address>(RawCode() + desc.instruction_offset);
DCHECK_LT(start, reinterpret_cast<Address>(code_ + code_size_));
if (pc < start) return false;
Address end = start + desc.instruction_length;
return pc < end;
}
Address EmbeddedData::InstructionStartOfBuiltin(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
......@@ -18,6 +29,15 @@ Address EmbeddedData::InstructionStartOfBuiltin(Builtin builtin) const {
return reinterpret_cast<Address>(result);
}
Address EmbeddedData::InstructionEndOf(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
const uint8_t* result =
RawCode() + desc.instruction_offset + desc.instruction_length;
DCHECK_LT(result, code_ + code_size_);
return reinterpret_cast<Address>(result);
}
uint32_t EmbeddedData::InstructionSizeOfBuiltin(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
......
......@@ -127,8 +127,11 @@ class EmbeddedData final {
data_ = nullptr;
}
inline bool BuiltinContains(Builtin builtin, Address pc) const;
// TODO(ishell): rename XyzOfBuiltin() to XyzOf().
inline Address InstructionStartOfBuiltin(Builtin builtin) const;
inline Address InstructionEndOf(Builtin builtin) const;
inline uint32_t InstructionSizeOfBuiltin(Builtin builtin) const;
inline Address InstructionStartOfBytecodeHandlers() const;
......
......@@ -264,17 +264,15 @@ TEST(TickEvents) {
frame3_code, "ddd");
PtrComprCageBase cage_base(isolate);
EnqueueTickSampleEvent(processor, frame1_code->InstructionStart(cage_base));
EnqueueTickSampleEvent(processor,
frame1_code->raw_instruction_start(cage_base));
EnqueueTickSampleEvent(processor,
frame2_code->raw_instruction_start(cage_base) +
frame2_code->raw_instruction_size(cage_base) / 2,
frame1_code->raw_instruction_start(cage_base) +
frame1_code->raw_instruction_size(cage_base) / 2);
EnqueueTickSampleEvent(processor,
frame3_code->raw_instruction_end(cage_base) - 1,
frame2_code->raw_instruction_end(cage_base) - 1,
frame1_code->raw_instruction_end(cage_base) - 1);
frame2_code->InstructionStart(cage_base) +
frame2_code->InstructionSize(cage_base) / 2,
frame1_code->InstructionStart(cage_base) +
frame1_code->InstructionSize(cage_base) / 2);
EnqueueTickSampleEvent(processor, frame3_code->InstructionEnd(cage_base) - 1,
frame2_code->InstructionEnd(cage_base) - 1,
frame1_code->InstructionEnd(cage_base) - 1);
isolate->v8_file_logger()->RemoveLogEventListener(&profiler_listener);
processor->StopSynchronously();
......@@ -1290,7 +1288,7 @@ static void TickLines(bool optimize) {
!CcTest::i_isolate()->use_optimizer());
i::Handle<i::AbstractCode> code(func->abstract_code(isolate), isolate);
CHECK(!code->is_null());
i::Address code_address = code->raw_instruction_start(isolate);
i::Address code_address = code->InstructionStart(isolate);
CHECK_NE(code_address, kNullAddress);
CodeEntryStorage storage;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment