[ext-code-space] Avoid Code <-> CodeT conversions in runtime, pt.1
This CL * adds forwarding accessors to CodeDataContainer for certain widely used Code object's fields and predicates, * adds JSFunction::set_code() overloads accepting CodeT values, * migrates SharedFunctionInfo getters to CodeT, * migrates InterpreterData::interpreter_trampoline to CodeT. Drive-by-fix: replace #if V8_EXTERNAL_CODE_SPACE with #ifdef to be consistent. Bug: v8:11880 Change-Id: I1e114076a0568068038ca6f70a86431a3a9cfb9f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3262716 Commit-Queue: Igor Sheludko <ishell@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/main@{#77762}
This commit is contained in:
parent
e8fe219a41
commit
13bcdc5b38
@ -77,7 +77,7 @@ bool AreStdlibMembersValid(Isolate* isolate, Handle<JSReceiver> stdlib,
|
||||
return false; \
|
||||
} \
|
||||
DCHECK_EQ(shared.GetCode(), \
|
||||
isolate->builtins()->code(Builtin::kMath##FName)); \
|
||||
isolate->builtins()->codet(Builtin::kMath##FName)); \
|
||||
}
|
||||
STDLIB_MATH_FUNCTION_LIST(STDLIB_MATH_FUNC)
|
||||
#undef STDLIB_MATH_FUNC
|
||||
|
@ -56,7 +56,7 @@ class BaselineCompilerTask {
|
||||
if (FLAG_print_code) {
|
||||
code->Print();
|
||||
}
|
||||
shared_function_info_->set_baseline_code(*code, kReleaseStore);
|
||||
shared_function_info_->set_baseline_code(ToCodeT(*code), kReleaseStore);
|
||||
if (V8_LIKELY(FLAG_use_osr)) {
|
||||
// Arm back edges for OSR
|
||||
shared_function_info_->GetBytecodeArray(isolate)
|
||||
|
@ -212,16 +212,18 @@ void Builtins::set_codet(Builtin builtin, CodeT code) {
|
||||
}
|
||||
|
||||
CodeT Builtins::codet(Builtin builtin) {
|
||||
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
|
||||
Address ptr =
|
||||
isolate_->builtin_code_data_container_table()[Builtins::ToInt(builtin)];
|
||||
Address* table = V8_EXTERNAL_CODE_SPACE_BOOL
|
||||
? isolate_->builtin_code_data_container_table()
|
||||
: isolate_->builtin_table();
|
||||
Address ptr = table[Builtins::ToInt(builtin)];
|
||||
return CodeT::cast(Object(ptr));
|
||||
}
|
||||
|
||||
Handle<CodeT> Builtins::codet_handle(Builtin builtin) {
|
||||
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
|
||||
Address* location =
|
||||
&isolate_->builtin_code_data_container_table()[Builtins::ToInt(builtin)];
|
||||
Address* table = V8_EXTERNAL_CODE_SPACE_BOOL
|
||||
? isolate_->builtin_code_data_container_table()
|
||||
: isolate_->builtin_table();
|
||||
Address* location = &table[Builtins::ToInt(builtin)];
|
||||
return Handle<CodeT>(location);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ static constexpr T FirstFromVarArgs(T x, ...) noexcept {
|
||||
#define BUILTIN_CODE(isolate, name) \
|
||||
(isolate)->builtins()->code_handle(i::Builtin::k##name)
|
||||
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
#define BUILTIN_CODET(isolate, name) \
|
||||
(isolate)->builtins()->codet_handle(i::Builtin::k##name)
|
||||
#else
|
||||
|
@ -553,7 +553,7 @@ void InstallInterpreterTrampolineCopy(
|
||||
INTERPRETER_DATA_TYPE, AllocationType::kOld));
|
||||
|
||||
interpreter_data->set_bytecode_array(*bytecode_array);
|
||||
interpreter_data->set_interpreter_trampoline(*code);
|
||||
interpreter_data->set_interpreter_trampoline(ToCodeT(*code));
|
||||
|
||||
shared_info->set_interpreter_data(*interpreter_data);
|
||||
|
||||
@ -1023,9 +1023,9 @@ Handle<Code> ContinuationForConcurrentOptimization(
|
||||
}
|
||||
return handle(function->code(), isolate);
|
||||
} else if (function->shared().HasBaselineCode()) {
|
||||
Code baseline_code = function->shared().baseline_code(kAcquireLoad);
|
||||
CodeT baseline_code = function->shared().baseline_code(kAcquireLoad);
|
||||
function->set_code(baseline_code);
|
||||
return handle(baseline_code, isolate);
|
||||
return handle(FromCodeT(baseline_code), isolate);
|
||||
}
|
||||
DCHECK(function->ActiveTierIsIgnition());
|
||||
return BUILTIN_CODE(isolate, InterpreterEntryTrampoline);
|
||||
@ -1921,7 +1921,7 @@ bool Compiler::Compile(Isolate* isolate, Handle<JSFunction> function,
|
||||
}
|
||||
|
||||
DCHECK(is_compiled_scope->is_compiled());
|
||||
Handle<Code> code = handle(shared_info->GetCode(), isolate);
|
||||
Handle<Code> code = handle(FromCodeT(shared_info->GetCode()), isolate);
|
||||
|
||||
// Initialize the feedback cell for this JSFunction and reset the interrupt
|
||||
// budget for feedback vector allocation even if there is a closure feedback
|
||||
@ -2005,7 +2005,7 @@ bool Compiler::CompileSharedWithBaseline(Isolate* isolate,
|
||||
// report these somehow, or silently ignore them?
|
||||
return false;
|
||||
}
|
||||
shared->set_baseline_code(*code, kReleaseStore);
|
||||
shared->set_baseline_code(ToCodeT(*code), kReleaseStore);
|
||||
|
||||
if (V8_LIKELY(FLAG_use_osr)) {
|
||||
// Arm back edges for OSR
|
||||
@ -2039,7 +2039,7 @@ bool Compiler::CompileBaseline(Isolate* isolate, Handle<JSFunction> function,
|
||||
// Baseline code needs a feedback vector.
|
||||
JSFunction::EnsureFeedbackVector(function, is_compiled_scope);
|
||||
|
||||
Code baseline_code = shared->baseline_code(kAcquireLoad);
|
||||
CodeT baseline_code = shared->baseline_code(kAcquireLoad);
|
||||
DCHECK_EQ(baseline_code.kind(), CodeKind::BASELINE);
|
||||
function->set_code(baseline_code);
|
||||
|
||||
|
@ -3797,7 +3797,7 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
|
||||
GetShortBuiltinsCallRegion().contains(heap_.code_region());
|
||||
}
|
||||
}
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
if (heap_.code_range()) {
|
||||
code_cage_base_ = GetPtrComprCageBaseAddress(heap_.code_range()->base());
|
||||
} else {
|
||||
|
@ -1088,7 +1088,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
|
||||
// address of the cage where the code space is allocated. Otherwise, it
|
||||
// defaults to cage_base().
|
||||
Address code_cage_base() const {
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
return code_cage_base_;
|
||||
#else
|
||||
return cage_base();
|
||||
@ -2127,7 +2127,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
|
||||
// favor memory over runtime performance.
|
||||
bool memory_savings_mode_active_ = false;
|
||||
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
// Base address of the pointer compression cage containing external code
|
||||
// space, when external code space is enabled.
|
||||
Address code_cage_base_ = 0;
|
||||
|
@ -3765,7 +3765,7 @@ Handle<JSFunction> Factory::JSFunctionBuilder::Build() {
|
||||
PrepareMap();
|
||||
PrepareFeedbackCell();
|
||||
|
||||
Handle<Code> code = handle(sfi_->GetCode(), isolate_);
|
||||
Handle<Code> code = handle(FromCodeT(sfi_->GetCode()), isolate_);
|
||||
Handle<JSFunction> result = BuildRaw(code);
|
||||
|
||||
if (code->kind() == CodeKind::BASELINE) {
|
||||
|
@ -3789,7 +3789,7 @@ class SlotCollectingVisitor final : public ObjectVisitor {
|
||||
|
||||
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
|
||||
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
code_slots_.push_back(slot);
|
||||
#endif
|
||||
}
|
||||
@ -3805,14 +3805,14 @@ class SlotCollectingVisitor final : public ObjectVisitor {
|
||||
int number_of_slots() { return static_cast<int>(slots_.size()); }
|
||||
|
||||
MaybeObjectSlot slot(int i) { return slots_[i]; }
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
CodeObjectSlot code_slot(int i) { return code_slots_[i]; }
|
||||
int number_of_code_slots() { return static_cast<int>(code_slots_.size()); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::vector<MaybeObjectSlot> slots_;
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
std::vector<CodeObjectSlot> code_slots_;
|
||||
#endif
|
||||
};
|
||||
@ -3860,7 +3860,7 @@ void Heap::VerifyObjectLayoutChange(HeapObject object, Map new_map) {
|
||||
for (int i = 0; i < new_visitor.number_of_slots(); i++) {
|
||||
DCHECK_EQ(new_visitor.slot(i), old_visitor.slot(i));
|
||||
}
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
DCHECK_EQ(new_visitor.number_of_code_slots(),
|
||||
old_visitor.number_of_code_slots());
|
||||
for (int i = 0; i < new_visitor.number_of_code_slots(); i++) {
|
||||
@ -6978,7 +6978,7 @@ Map Heap::GcSafeMapOfCodeSpaceObject(HeapObject object) {
|
||||
PtrComprCageBase cage_base(isolate());
|
||||
MapWord map_word = object.map_word(cage_base, kRelaxedLoad);
|
||||
if (map_word.IsForwardingAddress()) {
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
PtrComprCageBase code_cage_base(isolate()->code_cage_base());
|
||||
#else
|
||||
PtrComprCageBase code_cage_base = cage_base;
|
||||
|
@ -4053,7 +4053,7 @@ class RememberedSetUpdatingItem : public UpdatingItem {
|
||||
(chunk_->slot_set<OLD_TO_CODE, AccessMode::NON_ATOMIC>() !=
|
||||
nullptr)) {
|
||||
PtrComprCageBase cage_base = heap_->isolate();
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
PtrComprCageBase code_cage_base(heap_->isolate()->code_cage_base());
|
||||
#else
|
||||
PtrComprCageBase code_cage_base = cage_base;
|
||||
|
@ -2245,13 +2245,14 @@ void ExistingCodeLogger::LogCompiledFunctions() {
|
||||
LogExistingFunction(
|
||||
shared,
|
||||
Handle<AbstractCode>(
|
||||
AbstractCode::cast(shared->InterpreterTrampoline()), isolate_));
|
||||
AbstractCode::cast(FromCodeT(shared->InterpreterTrampoline())),
|
||||
isolate_));
|
||||
}
|
||||
if (shared->HasBaselineCode()) {
|
||||
LogExistingFunction(
|
||||
shared, Handle<AbstractCode>(
|
||||
AbstractCode::cast(shared->baseline_code(kAcquireLoad)),
|
||||
isolate_));
|
||||
LogExistingFunction(shared, Handle<AbstractCode>(
|
||||
AbstractCode::cast(FromCodeT(
|
||||
shared->baseline_code(kAcquireLoad))),
|
||||
isolate_));
|
||||
}
|
||||
if (pair.second.is_identical_to(BUILTIN_CODE(isolate_, CompileLazy)))
|
||||
continue;
|
||||
|
@ -292,7 +292,7 @@ CodeDataContainer Code::GCSafeCodeDataContainer(AcquireLoadTag) const {
|
||||
// Helper functions for converting Code objects to CodeDataContainer and back
|
||||
// when V8_EXTERNAL_CODE_SPACE is enabled.
|
||||
inline CodeT ToCodeT(Code code) {
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
return code.code_data_container(kAcquireLoad);
|
||||
#else
|
||||
return code;
|
||||
@ -300,7 +300,7 @@ inline CodeT ToCodeT(Code code) {
|
||||
}
|
||||
|
||||
inline Code FromCodeT(CodeT code) {
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
return code.code();
|
||||
#else
|
||||
return code;
|
||||
@ -308,7 +308,7 @@ inline Code FromCodeT(CodeT code) {
|
||||
}
|
||||
|
||||
inline Code FromCodeT(CodeT code, RelaxedLoadTag) {
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
return code.code(kRelaxedLoad);
|
||||
#else
|
||||
return code;
|
||||
@ -316,7 +316,7 @@ inline Code FromCodeT(CodeT code, RelaxedLoadTag) {
|
||||
}
|
||||
|
||||
inline CodeDataContainer CodeDataContainerFromCodeT(CodeT code) {
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
return code;
|
||||
#else
|
||||
return code.code_data_container(kAcquireLoad);
|
||||
@ -994,6 +994,35 @@ void CodeDataContainer::clear_padding() {
|
||||
kSize - kUnalignedSize);
|
||||
}
|
||||
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
//
|
||||
// A collection of getters and predicates that forward queries to associated
|
||||
// Code object.
|
||||
//
|
||||
|
||||
#define DEF_PRIMITIVE_FORWARDING_CDC_GETTER(name, type) \
|
||||
type CodeDataContainer::name() const { return FromCodeT(*this).name(); }
|
||||
|
||||
#define DEF_FORWARDING_CDC_GETTER(name, type) \
|
||||
DEF_GETTER(CodeDataContainer, name, type) { \
|
||||
return FromCodeT(*this).name(cage_base); \
|
||||
}
|
||||
|
||||
DEF_PRIMITIVE_FORWARDING_CDC_GETTER(kind, CodeKind)
|
||||
DEF_PRIMITIVE_FORWARDING_CDC_GETTER(builtin_id, Builtin)
|
||||
DEF_PRIMITIVE_FORWARDING_CDC_GETTER(is_builtin, bool)
|
||||
DEF_PRIMITIVE_FORWARDING_CDC_GETTER(is_interpreter_trampoline_builtin, bool)
|
||||
|
||||
DEF_FORWARDING_CDC_GETTER(deoptimization_data, FixedArray)
|
||||
DEF_FORWARDING_CDC_GETTER(bytecode_or_interpreter_data, HeapObject)
|
||||
DEF_FORWARDING_CDC_GETTER(source_position_table, ByteArray)
|
||||
DEF_FORWARDING_CDC_GETTER(bytecode_offset_table, ByteArray)
|
||||
|
||||
#undef DEF_PRIMITIVE_FORWARDING_CDC_GETTER
|
||||
#undef DEF_FORWARDING_CDC_GETTER
|
||||
|
||||
#endif // V8_EXTERNAL_CODE_SPACE
|
||||
|
||||
byte BytecodeArray::get(int index) const {
|
||||
DCHECK(index >= 0 && index < this->length());
|
||||
return ReadField<byte>(kHeaderSize + index * kCharSize);
|
||||
|
@ -85,6 +85,24 @@ class CodeDataContainer : public HeapObject {
|
||||
// Alias for code_entry_point to make it API compatible with Code.
|
||||
inline Address InstructionStart() const;
|
||||
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
//
|
||||
// A collection of getters and predicates that forward queries to associated
|
||||
// Code object.
|
||||
//
|
||||
|
||||
inline CodeKind kind() const;
|
||||
inline Builtin builtin_id() const;
|
||||
inline bool is_builtin() const;
|
||||
inline bool is_interpreter_trampoline_builtin() const;
|
||||
|
||||
DECL_GETTER(deoptimization_data, FixedArray)
|
||||
DECL_GETTER(bytecode_or_interpreter_data, HeapObject)
|
||||
DECL_GETTER(source_position_table, ByteArray)
|
||||
DECL_GETTER(bytecode_offset_table, ByteArray)
|
||||
|
||||
#endif // V8_EXTERNAL_CODE_SPACE
|
||||
|
||||
DECL_CAST(CodeDataContainer)
|
||||
|
||||
// Dispatched behavior.
|
||||
|
@ -155,6 +155,15 @@ void JSFunction::set_code(Code code, ReleaseStoreTag, WriteBarrierMode mode) {
|
||||
set_raw_code(ToCodeT(code), kReleaseStore, mode);
|
||||
}
|
||||
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
void JSFunction::set_code(CodeT code, WriteBarrierMode mode) {
|
||||
set_raw_code(code, mode);
|
||||
}
|
||||
void JSFunction::set_code(CodeT code, ReleaseStoreTag, WriteBarrierMode mode) {
|
||||
set_raw_code(code, kReleaseStore, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
Address JSFunction::code_entry_point() const {
|
||||
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
|
||||
return CodeDataContainer::cast(raw_code()).code_entry_point();
|
||||
|
@ -86,6 +86,14 @@ class JSFunction
|
||||
// are fully initialized.
|
||||
DECL_ACCESSORS(code, Code)
|
||||
DECL_RELEASE_ACQUIRE_ACCESSORS(code, Code)
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
// Convenient overloads to avoid unnecessary Code <-> CodeT conversions.
|
||||
// TODO(v8:11880): remove once |code| accessors are migrated to CodeT.
|
||||
inline void set_code(CodeT code,
|
||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
inline void set_code(CodeT code, ReleaseStoreTag,
|
||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
#endif
|
||||
|
||||
// Returns the address of the function code's instruction start.
|
||||
inline Address code_entry_point() const;
|
||||
|
@ -94,19 +94,6 @@ TQ_OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithoutPreparseData)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithPreparseData)
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(InterpreterData)
|
||||
|
||||
ACCESSORS(InterpreterData, raw_interpreter_trampoline, CodeT,
|
||||
kInterpreterTrampolineOffset)
|
||||
|
||||
DEF_GETTER(InterpreterData, interpreter_trampoline, Code) {
|
||||
return FromCodeT(raw_interpreter_trampoline(cage_base));
|
||||
}
|
||||
|
||||
void InterpreterData::set_interpreter_trampoline(Code code,
|
||||
WriteBarrierMode mode) {
|
||||
set_raw_interpreter_trampoline(ToCodeT(code), mode);
|
||||
}
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(SharedFunctionInfo)
|
||||
NEVER_READ_ONLY_SPACE_IMPL(SharedFunctionInfo)
|
||||
DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
|
||||
@ -211,7 +198,7 @@ AbstractCode SharedFunctionInfo::abstract_code(IsolateT* isolate) {
|
||||
if (HasBytecodeArray()) {
|
||||
return AbstractCode::cast(GetBytecodeArray(isolate));
|
||||
} else {
|
||||
return AbstractCode::cast(GetCode());
|
||||
return AbstractCode::cast(FromCodeT(GetCode()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -581,7 +568,7 @@ BytecodeArray SharedFunctionInfo::GetBytecodeArray(IsolateT* isolate) const {
|
||||
BytecodeArray SharedFunctionInfo::GetActiveBytecodeArray() const {
|
||||
Object data = function_data(kAcquireLoad);
|
||||
if (data.IsCodeT()) {
|
||||
Code baseline_code = FromCodeT(CodeT::cast(data));
|
||||
CodeT baseline_code = CodeT::cast(data);
|
||||
data = baseline_code.bytecode_or_interpreter_data();
|
||||
}
|
||||
if (data.IsBytecodeArray()) {
|
||||
@ -626,7 +613,7 @@ bool SharedFunctionInfo::ShouldFlushCode(
|
||||
// called by the concurrent marker.
|
||||
Object data = function_data(kAcquireLoad);
|
||||
if (data.IsCodeT()) {
|
||||
Code baseline_code = FromCodeT(CodeT::cast(data));
|
||||
CodeT baseline_code = CodeT::cast(data);
|
||||
DCHECK_EQ(baseline_code.kind(), CodeKind::BASELINE);
|
||||
// If baseline code flushing isn't enabled and we have baseline data on SFI
|
||||
// we cannot flush baseline / bytecode.
|
||||
@ -646,7 +633,7 @@ bool SharedFunctionInfo::ShouldFlushCode(
|
||||
return bytecode.IsOld();
|
||||
}
|
||||
|
||||
Code SharedFunctionInfo::InterpreterTrampoline() const {
|
||||
CodeT SharedFunctionInfo::InterpreterTrampoline() const {
|
||||
DCHECK(HasInterpreterData());
|
||||
return interpreter_data().interpreter_trampoline();
|
||||
}
|
||||
@ -654,7 +641,7 @@ Code SharedFunctionInfo::InterpreterTrampoline() const {
|
||||
bool SharedFunctionInfo::HasInterpreterData() const {
|
||||
Object data = function_data(kAcquireLoad);
|
||||
if (data.IsCodeT()) {
|
||||
Code baseline_code = FromCodeT(CodeT::cast(data));
|
||||
CodeT baseline_code = CodeT::cast(data);
|
||||
DCHECK_EQ(baseline_code.kind(), CodeKind::BASELINE);
|
||||
data = baseline_code.bytecode_or_interpreter_data();
|
||||
}
|
||||
@ -665,7 +652,7 @@ InterpreterData SharedFunctionInfo::interpreter_data() const {
|
||||
DCHECK(HasInterpreterData());
|
||||
Object data = function_data(kAcquireLoad);
|
||||
if (data.IsCodeT()) {
|
||||
Code baseline_code = FromCodeT(CodeT::cast(data));
|
||||
CodeT baseline_code = CodeT::cast(data);
|
||||
DCHECK_EQ(baseline_code.kind(), CodeKind::BASELINE);
|
||||
data = baseline_code.bytecode_or_interpreter_data();
|
||||
}
|
||||
@ -682,21 +669,21 @@ void SharedFunctionInfo::set_interpreter_data(
|
||||
bool SharedFunctionInfo::HasBaselineCode() const {
|
||||
Object data = function_data(kAcquireLoad);
|
||||
if (data.IsCodeT()) {
|
||||
DCHECK_EQ(FromCodeT(CodeT::cast(data)).kind(), CodeKind::BASELINE);
|
||||
DCHECK_EQ(CodeT::cast(data).kind(), CodeKind::BASELINE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Code SharedFunctionInfo::baseline_code(AcquireLoadTag) const {
|
||||
CodeT SharedFunctionInfo::baseline_code(AcquireLoadTag) const {
|
||||
DCHECK(HasBaselineCode());
|
||||
return FromCodeT(CodeT::cast(function_data(kAcquireLoad)));
|
||||
return CodeT::cast(function_data(kAcquireLoad));
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_baseline_code(Code baseline_code,
|
||||
void SharedFunctionInfo::set_baseline_code(CodeT baseline_code,
|
||||
ReleaseStoreTag) {
|
||||
DCHECK_EQ(baseline_code.kind(), CodeKind::BASELINE);
|
||||
set_function_data(ToCodeT(baseline_code), kReleaseStore);
|
||||
set_function_data(baseline_code, kReleaseStore);
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::FlushBaselineCode() {
|
||||
|
@ -68,7 +68,7 @@ void SharedFunctionInfo::Init(ReadOnlyRoots ro_roots, int unique_id) {
|
||||
clear_padding();
|
||||
}
|
||||
|
||||
Code SharedFunctionInfo::GetCode() const {
|
||||
CodeT SharedFunctionInfo::GetCode() const {
|
||||
// ======
|
||||
// NOTE: This chain of checks MUST be kept in sync with the equivalent CSA
|
||||
// GetSharedFunctionInfoCode method in code-stub-assembler.cc.
|
||||
@ -79,50 +79,50 @@ Code SharedFunctionInfo::GetCode() const {
|
||||
if (data.IsSmi()) {
|
||||
// Holding a Smi means we are a builtin.
|
||||
DCHECK(HasBuiltinId());
|
||||
return isolate->builtins()->code(builtin_id());
|
||||
return isolate->builtins()->codet(builtin_id());
|
||||
}
|
||||
if (data.IsBytecodeArray()) {
|
||||
// Having a bytecode array means we are a compiled, interpreted function.
|
||||
DCHECK(HasBytecodeArray());
|
||||
return isolate->builtins()->code(Builtin::kInterpreterEntryTrampoline);
|
||||
return isolate->builtins()->codet(Builtin::kInterpreterEntryTrampoline);
|
||||
}
|
||||
if (data.IsCodeT()) {
|
||||
// Having baseline Code means we are a compiled, baseline function.
|
||||
DCHECK(HasBaselineCode());
|
||||
return FromCodeT(CodeT::cast(data));
|
||||
return CodeT::cast(data);
|
||||
}
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
if (data.IsAsmWasmData()) {
|
||||
// Having AsmWasmData means we are an asm.js/wasm function.
|
||||
DCHECK(HasAsmWasmData());
|
||||
return isolate->builtins()->code(Builtin::kInstantiateAsmJs);
|
||||
return isolate->builtins()->codet(Builtin::kInstantiateAsmJs);
|
||||
}
|
||||
if (data.IsWasmExportedFunctionData()) {
|
||||
// Having a WasmExportedFunctionData means the code is in there.
|
||||
DCHECK(HasWasmExportedFunctionData());
|
||||
return wasm_exported_function_data().wrapper_code();
|
||||
return ToCodeT(wasm_exported_function_data().wrapper_code());
|
||||
}
|
||||
if (data.IsWasmJSFunctionData()) {
|
||||
return wasm_js_function_data().wrapper_code();
|
||||
return ToCodeT(wasm_js_function_data().wrapper_code());
|
||||
}
|
||||
if (data.IsWasmCapiFunctionData()) {
|
||||
return wasm_capi_function_data().wrapper_code();
|
||||
return ToCodeT(wasm_capi_function_data().wrapper_code());
|
||||
}
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
if (data.IsUncompiledData()) {
|
||||
// Having uncompiled data (with or without scope) means we need to compile.
|
||||
DCHECK(HasUncompiledData());
|
||||
return isolate->builtins()->code(Builtin::kCompileLazy);
|
||||
return isolate->builtins()->codet(Builtin::kCompileLazy);
|
||||
}
|
||||
if (data.IsFunctionTemplateInfo()) {
|
||||
// Having a function template info means we are an API function.
|
||||
DCHECK(IsApiFunction());
|
||||
return isolate->builtins()->code(Builtin::kHandleApiCall);
|
||||
return isolate->builtins()->codet(Builtin::kHandleApiCall);
|
||||
}
|
||||
if (data.IsInterpreterData()) {
|
||||
Code code = InterpreterTrampoline();
|
||||
DCHECK(code.IsCode());
|
||||
DCHECK(code.is_interpreter_trampoline_builtin());
|
||||
CodeT code = InterpreterTrampoline();
|
||||
DCHECK(code.IsCodeT());
|
||||
DCHECK(FromCodeT(code).is_interpreter_trampoline_builtin());
|
||||
return code;
|
||||
}
|
||||
UNREACHABLE();
|
||||
|
@ -144,11 +144,7 @@ class UncompiledDataWithPreparseData
|
||||
class InterpreterData
|
||||
: public TorqueGeneratedInterpreterData<InterpreterData, Struct> {
|
||||
public:
|
||||
DECL_ACCESSORS(interpreter_trampoline, Code)
|
||||
|
||||
private:
|
||||
DECL_ACCESSORS(raw_interpreter_trampoline, CodeT)
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS(InterpreterData)
|
||||
};
|
||||
|
||||
@ -176,7 +172,7 @@ class SharedFunctionInfo
|
||||
inline void SetName(String name);
|
||||
|
||||
// Get the code object which represents the execution of this function.
|
||||
V8_EXPORT_PRIVATE Code GetCode() const;
|
||||
V8_EXPORT_PRIVATE CodeT GetCode() const;
|
||||
|
||||
// Get the abstract code associated with the function, which will either be
|
||||
// a Code object or a BytecodeArray.
|
||||
@ -308,13 +304,13 @@ class SharedFunctionInfo
|
||||
inline BytecodeArray GetBytecodeArray(IsolateT* isolate) const;
|
||||
|
||||
inline void set_bytecode_array(BytecodeArray bytecode);
|
||||
inline Code InterpreterTrampoline() const;
|
||||
inline CodeT InterpreterTrampoline() const;
|
||||
inline bool HasInterpreterData() const;
|
||||
inline InterpreterData interpreter_data() const;
|
||||
inline void set_interpreter_data(InterpreterData interpreter_data);
|
||||
inline bool HasBaselineCode() const;
|
||||
inline Code baseline_code(AcquireLoadTag) const;
|
||||
inline void set_baseline_code(Code baseline_code, ReleaseStoreTag);
|
||||
inline CodeT baseline_code(AcquireLoadTag) const;
|
||||
inline void set_baseline_code(CodeT baseline_code, ReleaseStoreTag);
|
||||
inline void FlushBaselineCode();
|
||||
inline BytecodeArray GetActiveBytecodeArray() const;
|
||||
inline void SetActiveBytecodeArray(BytecodeArray bytecode);
|
||||
|
@ -197,7 +197,7 @@ class ObjectVisitorWithCageBases : public ObjectVisitor {
|
||||
// The pointer compression cage base value used for decompression of
|
||||
// references to Code objects.
|
||||
PtrComprCageBase code_cage_base() const {
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
return code_cage_base_;
|
||||
#else
|
||||
return cage_base();
|
||||
|
@ -91,10 +91,9 @@ RUNTIME_FUNCTION(Runtime_InstallBaselineCode) {
|
||||
DCHECK(!function->HasOptimizationMarker());
|
||||
DCHECK(!function->has_feedback_vector());
|
||||
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
|
||||
Code baseline_code = sfi->baseline_code(kAcquireLoad);
|
||||
CodeT baseline_code = sfi->baseline_code(kAcquireLoad);
|
||||
function->set_code(baseline_code);
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
return ToCodeT(baseline_code);
|
||||
return baseline_code;
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) {
|
||||
|
@ -259,7 +259,7 @@ void CreateInterpreterDataForDeserializedCode(Isolate* isolate,
|
||||
INTERPRETER_DATA_TYPE, AllocationType::kOld));
|
||||
|
||||
interpreter_data->set_bytecode_array(info->GetBytecodeArray(isolate));
|
||||
interpreter_data->set_interpreter_trampoline(*code);
|
||||
interpreter_data->set_interpreter_trampoline(ToCodeT(*code));
|
||||
|
||||
info->set_interpreter_data(*interpreter_data);
|
||||
|
||||
|
@ -900,7 +900,7 @@ void Serializer::ObjectSerializer::VisitCodePointer(HeapObject host,
|
||||
HandleScope scope(isolate());
|
||||
DisallowGarbageCollection no_gc;
|
||||
|
||||
#if V8_EXTERNAL_CODE_SPACE
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
PtrComprCageBase code_cage_base(isolate()->code_cage_base());
|
||||
#else
|
||||
PtrComprCageBase code_cage_base(isolate());
|
||||
|
@ -35,17 +35,15 @@ void ExpectSharedFunctionInfoState(SharedFunctionInfo sfi,
|
||||
HeapObject script_or_debug_info = sfi.script_or_debug_info(kAcquireLoad);
|
||||
switch (expectedState) {
|
||||
case SfiState::Compiled:
|
||||
CHECK(
|
||||
function_data.IsBytecodeArray() ||
|
||||
(function_data.IsCodeT() &&
|
||||
FromCodeT(CodeT::cast(function_data)).kind() == CodeKind::BASELINE));
|
||||
CHECK(function_data.IsBytecodeArray() ||
|
||||
(function_data.IsCodeT() &&
|
||||
CodeT::cast(function_data).kind() == CodeKind::BASELINE));
|
||||
CHECK(script_or_debug_info.IsScript());
|
||||
break;
|
||||
case SfiState::DebugInfo:
|
||||
CHECK(
|
||||
function_data.IsBytecodeArray() ||
|
||||
(function_data.IsCodeT() &&
|
||||
FromCodeT(CodeT::cast(function_data)).kind() == CodeKind::BASELINE));
|
||||
CHECK(function_data.IsBytecodeArray() ||
|
||||
(function_data.IsCodeT() &&
|
||||
CodeT::cast(function_data).kind() == CodeKind::BASELINE));
|
||||
CHECK(script_or_debug_info.IsDebugInfo());
|
||||
{
|
||||
DebugInfo debug_info = DebugInfo::cast(script_or_debug_info);
|
||||
|
@ -5047,11 +5047,11 @@ TEST(InterpreterWithNativeStack) {
|
||||
i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
|
||||
|
||||
CHECK(f->shared().HasBytecodeArray());
|
||||
i::Code code = f->shared().GetCode();
|
||||
i::Handle<i::Code> interpreter_entry_trampoline =
|
||||
BUILTIN_CODE(isolate, InterpreterEntryTrampoline);
|
||||
i::CodeT code = f->shared().GetCode();
|
||||
i::Handle<i::CodeT> interpreter_entry_trampoline =
|
||||
BUILTIN_CODET(isolate, InterpreterEntryTrampoline);
|
||||
|
||||
CHECK(code.IsCode());
|
||||
CHECK(code.IsCodeT());
|
||||
CHECK(code.is_interpreter_trampoline_builtin());
|
||||
CHECK_NE(code.address(), interpreter_entry_trampoline->address());
|
||||
}
|
||||
|
@ -2960,9 +2960,9 @@ TEST(AllocateFunctionWithMapAndContext) {
|
||||
CHECK(!fun->has_prototype_slot());
|
||||
CHECK_EQ(*isolate->factory()->promise_capability_default_resolve_shared_fun(),
|
||||
fun->shared());
|
||||
CHECK_EQ(isolate->factory()
|
||||
->promise_capability_default_resolve_shared_fun()
|
||||
->GetCode(),
|
||||
CHECK_EQ(FromCodeT(isolate->factory()
|
||||
->promise_capability_default_resolve_shared_fun()
|
||||
->GetCode()),
|
||||
fun->code());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user