[ext-code-space] Remove more Code <-> CodeT roundtrips

... in various components.

Bug: v8:11880
Change-Id: I1e4411ec38a4b15e505bda35a92987972e89d9d0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3777718
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Patrick Thier <pthier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81863}
This commit is contained in:
ishell@chromium.org 2022-07-21 11:22:39 +02:00 committed by V8 LUCI CQ
parent af39b32154
commit 91f98a8f7c
16 changed files with 109 additions and 71 deletions

View File

@ -114,7 +114,7 @@ const char* Builtins::Lookup(Address pc) {
if (!initialized_) return nullptr;
for (Builtin builtin_ix = Builtins::kFirst; builtin_ix <= Builtins::kLast;
++builtin_ix) {
if (FromCodeT(code(builtin_ix)).contains(isolate_, pc)) {
if (code(builtin_ix).contains(isolate_, pc)) {
return name(builtin_ix);
}
}
@ -341,16 +341,16 @@ void Builtins::EmitCodeCreateEvents(Isolate* isolate) {
int i = 0;
HandleScope scope(isolate);
for (; i < ToInt(Builtin::kFirstBytecodeHandler); i++) {
Code builtin_code = FromCodeT(CodeT::cast(Object(builtins[i])));
Handle<AbstractCode> code(AbstractCode::cast(builtin_code), isolate);
Handle<CodeT> builtin_code(&builtins[i]);
Handle<AbstractCode> code = ToAbstractCode(builtin_code, isolate);
PROFILE(isolate, CodeCreateEvent(LogEventListener::CodeTag::kBuiltin, code,
Builtins::name(FromInt(i))));
}
static_assert(kLastBytecodeHandlerPlusOne == kBuiltinCount);
for (; i < kBuiltinCount; i++) {
Code builtin_code = FromCodeT(CodeT::cast(Object(builtins[i])));
Handle<AbstractCode> code(AbstractCode::cast(builtin_code), isolate);
Handle<CodeT> builtin_code(&builtins[i]);
Handle<AbstractCode> code = ToAbstractCode(builtin_code, isolate);
interpreter::Bytecode bytecode =
builtin_metadata[i].data.bytecode_and_scale.bytecode;
interpreter::OperandScale scale =

View File

@ -4097,7 +4097,7 @@ Handle<JSFunction> Factory::JSFunctionBuilder::Build() {
PrepareMap();
PrepareFeedbackCell();
Handle<Code> code = handle(FromCodeT(sfi_->GetCode()), isolate_);
Handle<CodeT> code = handle(sfi_->GetCode(), isolate_);
Handle<JSFunction> result = BuildRaw(code);
if (code->kind() == CodeKind::BASELINE) {
@ -4109,7 +4109,7 @@ Handle<JSFunction> Factory::JSFunctionBuilder::Build() {
return result;
}
Handle<JSFunction> Factory::JSFunctionBuilder::BuildRaw(Handle<Code> code) {
Handle<JSFunction> Factory::JSFunctionBuilder::BuildRaw(Handle<CodeT> code) {
Isolate* isolate = isolate_;
Factory* factory = isolate_->factory();

View File

@ -911,7 +911,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
void PrepareMap();
void PrepareFeedbackCell();
V8_WARN_UNUSED_RESULT Handle<JSFunction> BuildRaw(Handle<Code> code);
V8_WARN_UNUSED_RESULT Handle<JSFunction> BuildRaw(Handle<CodeT> code);
Isolate* const isolate_;
Handle<SharedFunctionInfo> sfi_;

View File

@ -421,6 +421,13 @@ inline Handle<Code> FromCodeT(Handle<CodeT> code, Isolate* isolate) {
#endif
}
inline AbstractCode ToAbstractCode(CodeT code) {
if (V8_REMOVE_BUILTINS_CODE_OBJECTS) {
return AbstractCode::cast(code);
}
return AbstractCode::cast(FromCodeT(code));
}
inline Handle<AbstractCode> ToAbstractCode(Handle<CodeT> code,
Isolate* isolate) {
if (V8_REMOVE_BUILTINS_CODE_OBJECTS) {
@ -437,23 +444,34 @@ inline CodeDataContainer CodeDataContainerFromCodeT(CodeT code) {
#endif
}
CodeKind CodeLookupResult::kind() const {
DCHECK(IsFound());
#ifdef V8_EXTERNAL_CODE_SPACE
return IsCode() ? code().kind() : code_data_container().kind();
#define CODE_LOOKUP_RESULT_FWD_ACCESSOR(name, Type) \
Type CodeLookupResult::name() const { \
DCHECK(IsFound()); \
return IsCode() ? code().name() : code_data_container().name(); \
}
#else
return code().kind();
#define CODE_LOOKUP_RESULT_FWD_ACCESSOR(name, Type) \
Type CodeLookupResult::name() const { \
DCHECK(IsFound()); \
return code().name(); \
}
#endif
}
Builtin CodeLookupResult::builtin_id() const {
DCHECK(IsFound());
#ifdef V8_EXTERNAL_CODE_SPACE
return IsCode() ? code().builtin_id() : code_data_container().builtin_id();
#else
return code().builtin_id();
#endif
}
CODE_LOOKUP_RESULT_FWD_ACCESSOR(kind, CodeKind)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(builtin_id, Builtin)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(has_tagged_outgoing_params, bool)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(has_handler_table, bool)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(is_baseline_trampoline_builtin, bool)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(is_interpreter_trampoline_builtin, bool)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(is_baseline_leave_frame_builtin, bool)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(is_maglevved, bool)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(is_turbofanned, bool)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(stack_slots, int)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(GetBuiltinCatchPrediction,
HandlerTable::CatchPrediction)
#undef CODE_LOOKUP_RESULT_FWD_ACCESSOR
Code CodeLookupResult::ToCode() const {
#ifdef V8_EXTERNAL_CODE_SPACE
@ -896,11 +914,25 @@ inline bool Code::checks_tiering_state() const {
(CodeKindCanDeoptimize(kind()) && marked_for_deoptimization());
}
inline bool Code::has_tagged_outgoing_params() const {
return kind() != CodeKind::JS_TO_WASM_FUNCTION &&
kind() != CodeKind::C_WASM_ENTRY && kind() != CodeKind::WASM_FUNCTION;
namespace {
inline constexpr bool CodeKindHasTaggedOutgoingParams(CodeKind kind) {
return kind != CodeKind::JS_TO_WASM_FUNCTION &&
kind != CodeKind::C_WASM_ENTRY && kind != CodeKind::WASM_FUNCTION;
}
} // namespace
inline bool Code::has_tagged_outgoing_params() const {
return CodeKindHasTaggedOutgoingParams(kind());
}
#ifdef V8_EXTERNAL_CODE_SPACE
inline bool CodeDataContainer::has_tagged_outgoing_params() const {
return CodeKindHasTaggedOutgoingParams(kind());
}
#endif
inline bool Code::is_turbofanned() const {
const uint32_t flags = RELAXED_READ_UINT32_FIELD(*this, kFlagsOffset);
return IsTurbofannedField::decode(flags);

View File

@ -191,12 +191,15 @@ class CodeDataContainer : public HeapObject {
// For normal Code objects these functions just return the
// raw_instruction_start/end() values.
// 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;
V8_EXPORT_PRIVATE Address OffHeapInstructionStart(Isolate* isolate,
Address pc) const;
inline Address InstructionEnd(Isolate* isolate, Address pc) const;
V8_EXPORT_PRIVATE Address OffHeapInstructionEnd(Isolate* isolate,
Address pc) const;
V8_EXPORT_PRIVATE bool OffHeapBuiltinContains(Isolate* isolate,
Address pc) const;
inline Address InstructionEnd() const;
inline int InstructionSize() const;
@ -888,15 +891,20 @@ class CodeLookupResult {
#endif
}
// Helper method, in case of successful lookup returns the kind() of
// the Code/CodeDataContainer object found.
// It's safe use from GC.
// Helper methods, in case of successful lookup return the result of
// respective accessor of the Code/CodeDataContainer object found.
// It's safe use them from GC.
inline CodeKind kind() const;
// Helper method, in case of successful lookup returns the builtin_id() of
// the Code/CodeDataContainer object found.
// It's safe use from GC.
inline Builtin builtin_id() const;
inline bool has_tagged_outgoing_params() const;
inline bool has_handler_table() const;
inline bool is_baseline_trampoline_builtin() const;
inline bool is_interpreter_trampoline_builtin() const;
inline bool is_baseline_leave_frame_builtin() const;
inline bool is_maglevved() const;
inline bool is_turbofanned() const;
inline int stack_slots() const;
inline HandlerTable::CatchPrediction GetBuiltinCatchPrediction() const;
// Helper method, coverts the successful lookup result to Code object.
// It's not safe to be used from GC because conversion to Code might perform
@ -951,7 +959,10 @@ inline Code FromCodeT(CodeT code, AcquireLoadTag);
inline Code FromCodeT(CodeT code, PtrComprCageBase);
inline Code FromCodeT(CodeT code, PtrComprCageBase, RelaxedLoadTag);
inline Code FromCodeT(CodeT code, PtrComprCageBase, AcquireLoadTag);
inline Handle<CodeT> FromCodeT(Handle<Code> code, Isolate* isolate);
inline Handle<Code> FromCodeT(Handle<CodeT> code, Isolate* isolate);
inline AbstractCode ToAbstractCode(CodeT code);
inline Handle<AbstractCode> ToAbstractCode(Handle<CodeT> code,
Isolate* isolate);
inline CodeDataContainer CodeDataContainerFromCodeT(CodeT code);
// AbsractCode is an helper wrapper around {Code | BytecodeArray} or

View File

@ -1234,7 +1234,7 @@ KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const {
for (const MapAndHandler& map_and_handler : maps_and_handlers) {
const MaybeObjectHandle maybe_code_handler = map_and_handler.second;
// The first handler that isn't the slow handler will have the bits we need.
Handle<Code> handler;
Builtin builtin_handler = Builtin::kNoBuiltinId;
if (maybe_code_handler.object()->IsStoreHandler()) {
Handle<StoreHandler> data_handler =
Handle<StoreHandler>::cast(maybe_code_handler.object());
@ -1246,8 +1246,8 @@ KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const {
if (mode != STANDARD_STORE) return mode;
continue;
} else {
Code code = FromCodeT(CodeT::cast(data_handler->smi_handler()));
handler = config()->NewHandle(code);
CodeT code = CodeT::cast(data_handler->smi_handler());
builtin_handler = code.builtin_id();
}
} else if (maybe_code_handler.object()->IsSmi()) {
@ -1265,19 +1265,14 @@ KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const {
continue;
} else {
// Element store without prototype chain check.
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
Code code = FromCodeT(CodeT::cast(*maybe_code_handler.object()));
handler = config()->NewHandle(code);
} else {
handler = Handle<Code>::cast(maybe_code_handler.object());
}
CodeT code = CodeT::cast(*maybe_code_handler.object());
builtin_handler = code.builtin_id();
}
if (handler->is_builtin()) {
Builtin builtin = handler->builtin_id();
if (!BuiltinHasKeyedAccessStoreMode(builtin)) continue;
if (Builtins::IsBuiltinId(builtin_handler)) {
if (!BuiltinHasKeyedAccessStoreMode(builtin_handler)) continue;
mode = KeyedAccessStoreModeForBuiltin(builtin);
mode = KeyedAccessStoreModeForBuiltin(builtin_handler);
break;
}
}

View File

@ -63,7 +63,7 @@ AbstractCode JSFunction::abstract_code(IsolateT* isolate) {
if (ActiveTierIsIgnition()) {
return AbstractCode::cast(shared().GetBytecodeArray(isolate));
} else {
return AbstractCode::cast(FromCodeT(code(kAcquireLoad)));
return ToAbstractCode(code(kAcquireLoad));
}
}

View File

@ -351,7 +351,8 @@ bool HeapObject::IsAbstractCode() const {
return HeapObject::IsAbstractCode(cage_base);
}
bool HeapObject::IsAbstractCode(PtrComprCageBase cage_base) const {
return IsBytecodeArray(cage_base) || IsCode(cage_base);
return IsBytecodeArray(cage_base) || IsCode(cage_base) ||
(V8_REMOVE_BUILTINS_CODE_OBJECTS && IsCodeDataContainer(cage_base));
}
DEF_GETTER(HeapObject, IsStringWrapper, bool) {

View File

@ -197,10 +197,10 @@ template <typename IsolateT>
AbstractCode SharedFunctionInfo::abstract_code(IsolateT* isolate) {
// TODO(v8:11429): Decide if this return bytecode or baseline code, when the
// latter is present.
if (HasBytecodeArray()) {
if (HasBytecodeArray(isolate)) {
return AbstractCode::cast(GetBytecodeArray(isolate));
} else {
return AbstractCode::cast(FromCodeT(GetCode()));
return ToAbstractCode(GetCode());
}
}
@ -876,13 +876,13 @@ bool SharedFunctionInfo::is_repl_mode() const {
return script().IsScript() && Script::cast(script()).is_repl_mode();
}
bool SharedFunctionInfo::HasDebugInfo() const {
return script_or_debug_info(kAcquireLoad).IsDebugInfo();
DEF_GETTER(SharedFunctionInfo, HasDebugInfo, bool) {
return script_or_debug_info(cage_base, kAcquireLoad).IsDebugInfo(cage_base);
}
DebugInfo SharedFunctionInfo::GetDebugInfo() const {
auto debug_info = script_or_debug_info(kAcquireLoad);
DCHECK(debug_info.IsDebugInfo());
DEF_GETTER(SharedFunctionInfo, GetDebugInfo, DebugInfo) {
auto debug_info = script_or_debug_info(cage_base, kAcquireLoad);
DCHECK(debug_info.IsDebugInfo(cage_base));
return DebugInfo::cast(debug_info);
}

View File

@ -416,8 +416,8 @@ class SharedFunctionInfo
inline bool is_repl_mode() const;
// The function is subject to debugging if a debug info is attached.
inline bool HasDebugInfo() const;
inline DebugInfo GetDebugInfo() const;
DECL_GETTER(HasDebugInfo, bool)
DECL_GETTER(GetDebugInfo, DebugInfo)
inline void SetDebugInfo(DebugInfo debug_info);
// The offset of the 'function' token in the script source relative to the

View File

@ -412,7 +412,7 @@ void ProfilerCodeObserver::LogBuiltins() {
++builtin) {
CodeEventsContainer evt_rec(CodeEventRecord::Type::kReportBuiltin);
ReportBuiltinEventRecord* rec = &evt_rec.ReportBuiltinEventRecord_;
Code code = FromCodeT(builtins->code(builtin));
CodeT code = builtins->code(builtin);
rec->instruction_start = code.InstructionStart();
rec->instruction_size = code.InstructionSize();
rec->builtin = builtin;

View File

@ -405,9 +405,9 @@ RUNTIME_FUNCTION(Runtime_CompileOptimizedOSR) {
UnoptimizedFrame* frame = UnoptimizedFrame::cast(it.frame());
DCHECK_IMPLIES(frame->is_interpreted(),
frame->LookupCode().is_interpreter_trampoline_builtin());
frame->LookupCodeT().is_interpreter_trampoline_builtin());
DCHECK_IMPLIES(frame->is_baseline(),
frame->LookupCode().kind() == CodeKind::BASELINE);
frame->LookupCodeT().kind() == CodeKind::BASELINE);
DCHECK(frame->function().shared().HasBytecodeArray());
// Determine the entry point for which this OSR request has been fired.

View File

@ -131,7 +131,7 @@ void Serializer::SerializeObject(Handle<HeapObject> obj) {
if (obj->IsThinString(isolate())) {
obj = handle(ThinString::cast(*obj).actual(isolate()), isolate());
} else if (obj->IsCodeT(isolate())) {
Code code = FromCodeT(CodeT::cast(*obj));
CodeT code = CodeT::cast(*obj);
if (code.kind() == CodeKind::BASELINE) {
// For now just serialize the BytecodeArray instead of baseline code.
// TODO(v8:11429,pthier): Handle Baseline code in cases we want to

View File

@ -533,8 +533,7 @@ static void StackCheck(Local<String> name,
for (int i = 0; !iter.done(); i++) {
i::StackFrame* frame = iter.frame();
CHECK(i != 0 || (frame->type() == i::StackFrame::EXIT));
i::Code code = frame->LookupCode();
CHECK(code.IsCode());
i::CodeT code = frame->LookupCodeT().ToCodeT();
CHECK(code.contains(isolate, frame->pc()));
iter.Advance();
}

View File

@ -4496,7 +4496,7 @@ TEST(BuiltinsExceptionPrediction) {
bool fail = false;
for (i::Builtin builtin = i::Builtins::kFirst; builtin <= i::Builtins::kLast;
++builtin) {
i::Code code = FromCodeT(builtins->code(builtin));
i::CodeT code = builtins->code(builtin);
if (code.kind() != i::CodeKind::BUILTIN) continue;
auto prediction = code.GetBuiltinCatchPrediction();
USE(prediction);

View File

@ -168,7 +168,7 @@ TEST(Unwind_BuiltinPCInMiddle_Success_CodePagesAPI) {
register_state.fp = stack;
// Put the current PC inside of a valid builtin.
Code builtin = FromCodeT(i_isolate->builtins()->code(Builtin::kStringEqual));
CodeT builtin = *BUILTIN_CODE(i_isolate, StringEqual);
const uintptr_t offset = 40;
CHECK_LT(offset, builtin.InstructionSize());
register_state.pc =
@ -225,7 +225,7 @@ TEST(Unwind_BuiltinPCAtStart_Success_CodePagesAPI) {
// Put the current PC at the start of a valid builtin, so that we are setting
// up the frame.
Code builtin = FromCodeT(i_isolate->builtins()->code(Builtin::kStringEqual));
CodeT builtin = *BUILTIN_CODE(i_isolate, StringEqual);
register_state.pc = reinterpret_cast<void*>(builtin.InstructionStart());
bool unwound = v8::Unwinder::TryUnwindV8Frames(
@ -457,7 +457,7 @@ TEST(Unwind_JSEntry_Fail_CodePagesAPI) {
CHECK_LE(pages_length, arraysize(code_pages));
RegisterState register_state;
Code js_entry = FromCodeT(i_isolate->builtins()->code(Builtin::kJSEntry));
CodeT js_entry = *BUILTIN_CODE(i_isolate, JSEntry);
byte* start = reinterpret_cast<byte*>(js_entry.InstructionStart());
register_state.pc = start + 10;
@ -639,7 +639,7 @@ TEST(PCIsInV8_InJSEntryRange_CodePagesAPI) {
isolate->CopyCodePages(arraysize(code_pages), code_pages);
CHECK_LE(pages_length, arraysize(code_pages));
Code js_entry = FromCodeT(i_isolate->builtins()->code(Builtin::kJSEntry));
CodeT js_entry = *BUILTIN_CODE(i_isolate, JSEntry);
byte* start = reinterpret_cast<byte*>(js_entry.InstructionStart());
size_t length = js_entry.InstructionSize();