[ext-code-space] Avoid Code <-> CodeT conversions in runtime, pt.2
This CL migrates JSFunction's code accessors to CodeT. Bug: v8:11880 Change-Id: I8cf367eb79cc1d59548dd4f3e18c010f76f101cb Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3330466 Reviewed-by: Nico Hartmann <nicohartmann@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/main@{#78365}
This commit is contained in:
parent
25601fb9db
commit
a0108291e2
@ -1020,9 +1020,11 @@ Handle<Code> ContinuationForConcurrentOptimization(
|
||||
// into the feedback vector.
|
||||
STATIC_ASSERT(
|
||||
FeedbackVector::kFeedbackVectorMaybeOptimizedCodeIsStoreRelease);
|
||||
function->set_code(function->feedback_vector().optimized_code());
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
function->set_code(ToCodeT(function->feedback_vector().optimized_code()));
|
||||
}
|
||||
return handle(function->code(), isolate);
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
return handle(FromCodeT(function->code()), isolate);
|
||||
} else if (function->shared().HasBaselineCode()) {
|
||||
CodeT baseline_code = function->shared().baseline_code(kAcquireLoad);
|
||||
function->set_code(baseline_code);
|
||||
@ -3304,17 +3306,19 @@ void Compiler::PostInstantiation(Handle<JSFunction> function) {
|
||||
function->feedback_vector().EvictOptimizedCodeMarkedForDeoptimization(
|
||||
function->raw_feedback_cell(), *shared,
|
||||
"new function from shared function info");
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
Code code = function->feedback_vector().optimized_code();
|
||||
if (!code.is_null()) {
|
||||
CodeT codet = ToCodeT(code);
|
||||
// Caching of optimized code enabled and optimized code found.
|
||||
DCHECK(!code.marked_for_deoptimization());
|
||||
DCHECK(!codet.marked_for_deoptimization());
|
||||
DCHECK(function->shared().is_compiled());
|
||||
|
||||
// We don't need a release store because the optimized code was
|
||||
// stored with release semantics into the vector
|
||||
STATIC_ASSERT(
|
||||
FeedbackVector::kFeedbackVectorMaybeOptimizedCodeIsStoreRelease);
|
||||
function->set_code(code);
|
||||
function->set_code(codet);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2775,7 +2775,8 @@ BIMODAL_ACCESSOR(JSFunction, SharedFunctionInfo, shared)
|
||||
#undef JSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP_C
|
||||
|
||||
CodeRef JSFunctionRef::code() const {
|
||||
return MakeRefAssumeMemoryFence(broker(), object()->code(kAcquireLoad));
|
||||
return MakeRefAssumeMemoryFence(broker(),
|
||||
FromCodeT(object()->code(kAcquireLoad)));
|
||||
}
|
||||
|
||||
NativeContextRef JSFunctionRef::native_context() const {
|
||||
|
@ -1361,7 +1361,7 @@ void Debug::DiscardBaselineCode(SharedFunctionInfo shared) {
|
||||
isolate->thread_manager()->IterateArchivedThreads(&visitor);
|
||||
// TODO(v8:11429): Avoid this heap walk somehow.
|
||||
HeapObjectIterator iterator(isolate->heap());
|
||||
auto trampoline = BUILTIN_CODE(isolate, InterpreterEntryTrampoline);
|
||||
auto trampoline = BUILTIN_CODET(isolate, InterpreterEntryTrampoline);
|
||||
shared.FlushBaselineCode();
|
||||
for (HeapObject obj = iterator.Next(); !obj.is_null();
|
||||
obj = iterator.Next()) {
|
||||
@ -1379,7 +1379,7 @@ void Debug::DiscardAllBaselineCode() {
|
||||
DiscardBaselineCodeVisitor visitor;
|
||||
visitor.VisitThread(isolate_, isolate_->thread_local_top());
|
||||
HeapObjectIterator iterator(isolate_->heap());
|
||||
auto trampoline = BUILTIN_CODE(isolate_, InterpreterEntryTrampoline);
|
||||
auto trampoline = BUILTIN_CODET(isolate_, InterpreterEntryTrampoline);
|
||||
isolate_->thread_manager()->IterateArchivedThreads(&visitor);
|
||||
for (HeapObject obj = iterator.Next(); !obj.is_null();
|
||||
obj = iterator.Next()) {
|
||||
@ -1490,7 +1490,7 @@ void Debug::InstallDebugBreakTrampoline() {
|
||||
|
||||
if (!needs_to_use_trampoline) return;
|
||||
|
||||
Handle<Code> trampoline = BUILTIN_CODE(isolate_, DebugBreakTrampoline);
|
||||
Handle<CodeT> trampoline = BUILTIN_CODET(isolate_, DebugBreakTrampoline);
|
||||
std::vector<Handle<JSFunction>> needs_compile;
|
||||
{
|
||||
HeapObjectIterator iterator(isolate_->heap());
|
||||
|
@ -431,7 +431,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction function, Code code) {
|
||||
TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
|
||||
TRACE_EVENT0("v8", "V8.DeoptimizeCode");
|
||||
function.ResetIfCodeFlushed();
|
||||
if (code.is_null()) code = function.code();
|
||||
if (code.is_null()) code = FromCodeT(function.code());
|
||||
|
||||
if (CodeKindCanDeoptimize(code.kind())) {
|
||||
// Mark the code for deoptimization and unlink any functions that also
|
||||
|
@ -853,8 +853,8 @@ void JSFunction::JSFunctionVerify(Isolate* isolate) {
|
||||
CHECK(context(isolate, kRelaxedLoad).IsContext());
|
||||
VerifyPointer(isolate, raw_feedback_cell(isolate));
|
||||
CHECK(raw_feedback_cell(isolate).IsFeedbackCell());
|
||||
VerifyPointer(isolate, raw_code(isolate));
|
||||
CHECK(raw_code(isolate).IsCodeT());
|
||||
VerifyPointer(isolate, code(isolate));
|
||||
CHECK(code(isolate).IsCodeT());
|
||||
CHECK(map(isolate).is_callable());
|
||||
Handle<JSFunction> function(*this, isolate);
|
||||
LookupIterator it(isolate, function, isolate->factory()->prototype_string(),
|
||||
|
@ -1516,7 +1516,7 @@ void JSFunction::JSFunctionPrint(std::ostream& os) {
|
||||
<< shared().internal_formal_parameter_count_without_receiver();
|
||||
os << "\n - kind: " << shared().kind();
|
||||
os << "\n - context: " << Brief(context());
|
||||
os << "\n - code: " << Brief(raw_code());
|
||||
os << "\n - code: " << Brief(code());
|
||||
if (code().kind() == CodeKind::FOR_TESTING) {
|
||||
os << "\n - FOR_TESTING";
|
||||
} else if (ActiveTierIsIgnition()) {
|
||||
|
@ -1282,7 +1282,7 @@ bool JavaScriptFrame::HasInlinedFrames() const {
|
||||
}
|
||||
|
||||
Code CommonFrameWithJSLinkage::unchecked_code() const {
|
||||
return function().code();
|
||||
return FromCodeT(function().code());
|
||||
}
|
||||
|
||||
int OptimizedFrame::ComputeParametersCount() const {
|
||||
@ -1807,7 +1807,7 @@ DeoptimizationData OptimizedFrame::GetDeoptimizationData(
|
||||
DCHECK(is_optimized());
|
||||
|
||||
JSFunction opt_function = function();
|
||||
Code code = opt_function.code();
|
||||
Code code = FromCodeT(opt_function.code());
|
||||
|
||||
// The code object may have been replaced by lazy deoptimization. Fall
|
||||
// back to a slow search in this case to find the original optimized
|
||||
|
@ -736,7 +736,8 @@ class StackTraceBuilder {
|
||||
|
||||
Handle<Object> receiver(combinator->native_context().promise_function(),
|
||||
isolate_);
|
||||
Handle<Code> code(combinator->code(), isolate_);
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
Handle<Code> code(FromCodeT(combinator->code()), isolate_);
|
||||
|
||||
// TODO(mmarchini) save Promises list from the Promise combinator
|
||||
Handle<FixedArray> parameters = isolate_->factory()->empty_fixed_array();
|
||||
@ -911,7 +912,7 @@ namespace {
|
||||
bool IsBuiltinFunction(Isolate* isolate, HeapObject object, Builtin builtin) {
|
||||
if (!object.IsJSFunction()) return false;
|
||||
JSFunction const function = JSFunction::cast(object);
|
||||
return function.code() == isolate->builtins()->code(builtin);
|
||||
return function.code() == isolate->builtins()->codet(builtin);
|
||||
}
|
||||
|
||||
void CaptureAsyncStackTrace(Isolate* isolate, Handle<JSPromise> promise,
|
||||
|
@ -1912,7 +1912,7 @@ EnumerateCompiledFunctions(Heap* heap) {
|
||||
Script::cast(function.shared().script()).HasValidSource()) {
|
||||
compiled_funcs.emplace_back(
|
||||
handle(function.shared(), isolate),
|
||||
handle(AbstractCode::cast(function.code()), isolate));
|
||||
handle(AbstractCode::cast(FromCodeT(function.code())), isolate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ TQ_OBJECT_CONSTRUCTORS_IMPL(BytecodeArray)
|
||||
OBJECT_CONSTRUCTORS_IMPL(AbstractCode, HeapObject)
|
||||
OBJECT_CONSTRUCTORS_IMPL(DependentCode, WeakArrayList)
|
||||
OBJECT_CONSTRUCTORS_IMPL(CodeDataContainer, HeapObject)
|
||||
NEVER_READ_ONLY_SPACE_IMPL(CodeDataContainer)
|
||||
|
||||
NEVER_READ_ONLY_SPACE_IMPL(AbstractCode)
|
||||
|
||||
@ -551,6 +552,19 @@ inline bool Code::is_baseline_leave_frame_builtin() const {
|
||||
return builtin_id() == Builtin::kBaselineLeaveFrame;
|
||||
}
|
||||
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
// Note, must be in sync with Code::checks_optimization_marker().
|
||||
inline bool CodeDataContainer::checks_optimization_marker() const {
|
||||
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
|
||||
bool checks_marker = (builtin_id() == Builtin::kCompileLazy ||
|
||||
builtin_id() == Builtin::kInterpreterEntryTrampoline ||
|
||||
CodeKindCanTierUp(kind()));
|
||||
return checks_marker ||
|
||||
(CodeKindCanDeoptimize(kind()) && marked_for_deoptimization());
|
||||
}
|
||||
#endif // V8_EXTERNAL_CODE_SPACE
|
||||
|
||||
// Note, must be in sync with CodeDataContainer::checks_optimization_marker().
|
||||
inline bool Code::checks_optimization_marker() const {
|
||||
bool checks_marker = (builtin_id() == Builtin::kCompileLazy ||
|
||||
builtin_id() == Builtin::kInterpreterEntryTrampoline ||
|
||||
@ -661,20 +675,35 @@ int Code::stack_slots() const {
|
||||
return StackSlotsField::decode(flags);
|
||||
}
|
||||
|
||||
bool CodeDataContainer::marked_for_deoptimization() const {
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
// kind field is not available on CodeDataContainer when external code space
|
||||
// is not enabled.
|
||||
DCHECK(CodeKindCanDeoptimize(kind()));
|
||||
#endif // V8_EXTERNAL_CODE_SPACE
|
||||
int32_t flags = kind_specific_flags(kRelaxedLoad);
|
||||
return Code::MarkedForDeoptimizationField::decode(flags);
|
||||
}
|
||||
|
||||
bool Code::marked_for_deoptimization() const {
|
||||
DCHECK(CodeKindCanDeoptimize(kind()));
|
||||
int32_t flags =
|
||||
code_data_container(kAcquireLoad).kind_specific_flags(kRelaxedLoad);
|
||||
return MarkedForDeoptimizationField::decode(flags);
|
||||
return code_data_container(kAcquireLoad).marked_for_deoptimization();
|
||||
}
|
||||
|
||||
void CodeDataContainer::set_marked_for_deoptimization(bool flag) {
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
// kind field is not available on CodeDataContainer when external code space
|
||||
// is not enabled.
|
||||
DCHECK(CodeKindCanDeoptimize(kind()));
|
||||
#endif // V8_EXTERNAL_CODE_SPACE
|
||||
DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
|
||||
int32_t previous = kind_specific_flags(kRelaxedLoad);
|
||||
int32_t updated = Code::MarkedForDeoptimizationField::update(previous, flag);
|
||||
set_kind_specific_flags(updated, kRelaxedStore);
|
||||
}
|
||||
|
||||
void Code::set_marked_for_deoptimization(bool flag) {
|
||||
DCHECK(CodeKindCanDeoptimize(kind()));
|
||||
DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
|
||||
CodeDataContainer container = code_data_container(kAcquireLoad);
|
||||
int32_t previous = container.kind_specific_flags(kRelaxedLoad);
|
||||
int32_t updated = MarkedForDeoptimizationField::update(previous, flag);
|
||||
container.set_kind_specific_flags(updated, kRelaxedStore);
|
||||
code_data_container(kAcquireLoad).set_marked_for_deoptimization(flag);
|
||||
}
|
||||
|
||||
int Code::deoptimization_count() const {
|
||||
@ -1016,6 +1045,8 @@ inline bool CodeDataContainer::is_interpreter_trampoline_builtin() const {
|
||||
return FromCodeT(*this).name(cage_base); \
|
||||
}
|
||||
|
||||
DEF_PRIMITIVE_FORWARDING_CDC_GETTER(is_turbofanned, 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)
|
||||
|
@ -53,6 +53,18 @@ class CodeDataContainer : public HeapObject {
|
||||
// is deterministic.
|
||||
inline void clear_padding();
|
||||
|
||||
//
|
||||
// A collection of getters and predicates that are used by respective methods
|
||||
// on Code object. They are defined here mostly because they operate on the
|
||||
// writable state of the respective Code object.
|
||||
//
|
||||
|
||||
inline bool can_have_weak_objects() const;
|
||||
inline void set_can_have_weak_objects(bool value);
|
||||
|
||||
inline bool marked_for_deoptimization() const;
|
||||
inline void set_marked_for_deoptimization(bool flag);
|
||||
|
||||
// Back-reference to the Code object.
|
||||
// Available only when V8_EXTERNAL_CODE_SPACE is defined.
|
||||
DECL_GETTER(code, Code)
|
||||
@ -99,8 +111,28 @@ class CodeDataContainer : public HeapObject {
|
||||
inline CodeKind kind() const;
|
||||
inline Builtin builtin_id() const;
|
||||
inline bool is_builtin() const;
|
||||
|
||||
inline bool is_optimized_code() const;
|
||||
inline bool is_wasm_code() const;
|
||||
|
||||
// Testers for interpreter builtins.
|
||||
inline bool is_interpreter_trampoline_builtin() const;
|
||||
|
||||
// Testers for baseline builtins.
|
||||
inline bool is_baseline_trampoline_builtin() const;
|
||||
inline bool is_baseline_leave_frame_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_outgoing_params() const;
|
||||
|
||||
// [is_turbofanned]: Tells whether the code object was generated by the
|
||||
// TurboFan optimizing compiler.
|
||||
inline bool is_turbofanned() const;
|
||||
|
||||
DECL_GETTER(deoptimization_data, FixedArray)
|
||||
DECL_GETTER(bytecode_or_interpreter_data, HeapObject)
|
||||
DECL_GETTER(source_position_table, ByteArray)
|
||||
|
@ -132,41 +132,24 @@ AbstractCode JSFunction::abstract_code(IsolateT* isolate) {
|
||||
if (ActiveTierIsIgnition()) {
|
||||
return AbstractCode::cast(shared().GetBytecodeArray(isolate));
|
||||
} else {
|
||||
return AbstractCode::cast(code(kAcquireLoad));
|
||||
return AbstractCode::cast(FromCodeT(code(kAcquireLoad)));
|
||||
}
|
||||
}
|
||||
|
||||
int JSFunction::length() { return shared().length(); }
|
||||
|
||||
ACCESSORS_RELAXED(JSFunction, raw_code, CodeT, kCodeOffset)
|
||||
RELEASE_ACQUIRE_ACCESSORS(JSFunction, raw_code, CodeT, kCodeOffset)
|
||||
|
||||
DEF_GETTER(JSFunction, code, Code) { return FromCodeT(raw_code(cage_base)); }
|
||||
|
||||
void JSFunction::set_code(Code code, WriteBarrierMode mode) {
|
||||
set_raw_code(ToCodeT(code), mode);
|
||||
}
|
||||
|
||||
DEF_ACQUIRE_GETTER(JSFunction, code, Code) {
|
||||
return FromCodeT(raw_code(cage_base, kAcquireLoad));
|
||||
}
|
||||
|
||||
void JSFunction::set_code(Code code, ReleaseStoreTag, WriteBarrierMode mode) {
|
||||
set_raw_code(ToCodeT(code), kReleaseStore, mode);
|
||||
}
|
||||
ACCESSORS_RELAXED(JSFunction, code, CodeT, kCodeOffset)
|
||||
RELEASE_ACQUIRE_ACCESSORS(JSFunction, code, CodeT, kCodeOffset)
|
||||
|
||||
#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);
|
||||
void JSFunction::set_code(Code code, ReleaseStoreTag, WriteBarrierMode mode) {
|
||||
set_code(ToCodeT(code), kReleaseStore, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
Address JSFunction::code_entry_point() const {
|
||||
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
|
||||
return CodeDataContainer::cast(raw_code()).code_entry_point();
|
||||
return CodeDataContainer::cast(code()).code_entry_point();
|
||||
} else {
|
||||
return code().InstructionStart();
|
||||
}
|
||||
@ -348,7 +331,7 @@ void JSFunction::ResetIfCodeFlushed(
|
||||
if (kBytecodeCanFlush && NeedsResetDueToFlushedBytecode()) {
|
||||
// Bytecode was flushed and function is now uncompiled, reset JSFunction
|
||||
// by setting code to CompileLazy and clearing the feedback vector.
|
||||
set_code(*BUILTIN_CODE(GetIsolate(), CompileLazy));
|
||||
set_code(*BUILTIN_CODET(GetIsolate(), CompileLazy));
|
||||
raw_feedback_cell().reset_feedback_vector(gc_notify_updated_slot);
|
||||
return;
|
||||
}
|
||||
@ -356,7 +339,7 @@ void JSFunction::ResetIfCodeFlushed(
|
||||
DCHECK_IMPLIES(NeedsResetDueToFlushedBaselineCode(), kBaselineCodeCanFlush);
|
||||
if (kBaselineCodeCanFlush && NeedsResetDueToFlushedBaselineCode()) {
|
||||
// Flush baseline code from the closure if required
|
||||
set_code(*BUILTIN_CODE(GetIsolate(), InterpreterEntryTrampoline));
|
||||
set_code(*BUILTIN_CODET(GetIsolate(), InterpreterEntryTrampoline));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,14 +84,12 @@ class JSFunction
|
||||
// optimized code object, or when reading from the background thread.
|
||||
// Storing a builtin doesn't require release semantics because these objects
|
||||
// are fully initialized.
|
||||
DECL_ACCESSORS(code, Code)
|
||||
DECL_RELEASE_ACQUIRE_ACCESSORS(code, Code)
|
||||
DECL_ACCESSORS(code, CodeT)
|
||||
DECL_RELEASE_ACQUIRE_ACCESSORS(code, CodeT)
|
||||
#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,
|
||||
inline void set_code(Code code, ReleaseStoreTag,
|
||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
||||
#endif
|
||||
|
||||
@ -317,9 +315,6 @@ class JSFunction
|
||||
class BodyDescriptor;
|
||||
|
||||
private:
|
||||
DECL_ACCESSORS(raw_code, CodeT)
|
||||
DECL_RELEASE_ACQUIRE_ACCESSORS(raw_code, CodeT)
|
||||
|
||||
// JSFunction doesn't have a fixed header size:
|
||||
// Hide TorqueGeneratedClass::kHeaderSize to avoid confusion.
|
||||
static const int kHeaderSize;
|
||||
|
@ -147,6 +147,7 @@ Code OSROptimizedCodeCache::GetCodeFromEntry(int index) {
|
||||
Get(index + OSRCodeCacheConstants::kCachedCodeOffset)
|
||||
->GetHeapObject(&code_entry);
|
||||
if (code_entry.is_null()) return Code();
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
return FromCodeT(CodeT::cast(code_entry));
|
||||
}
|
||||
|
||||
@ -194,6 +195,7 @@ void OSROptimizedCodeCache::InitializeEntry(int entry,
|
||||
BytecodeOffset osr_offset) {
|
||||
Set(entry + OSRCodeCacheConstants::kSharedOffset,
|
||||
HeapObjectReference::Weak(shared));
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
HeapObjectReference weak_code_entry =
|
||||
HeapObjectReference::Weak(ToCodeT(code));
|
||||
Set(entry + OSRCodeCacheConstants::kCachedCodeOffset, weak_code_entry);
|
||||
|
@ -45,8 +45,7 @@ Object CompileOptimized(Isolate* isolate, Handle<JSFunction> function,
|
||||
// As a post-condition of CompileOptimized, the function *must* be compiled,
|
||||
// i.e. the installed Code object must not be the CompileLazy builtin.
|
||||
DCHECK(function->is_compiled());
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
return ToCodeT(function->code());
|
||||
return function->code();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -76,8 +75,7 @@ RUNTIME_FUNCTION(Runtime_CompileLazy) {
|
||||
return ReadOnlyRoots(isolate).exception();
|
||||
}
|
||||
DCHECK(function->is_compiled());
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
return ToCodeT(function->code());
|
||||
return function->code();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_InstallBaselineCode) {
|
||||
@ -127,8 +125,7 @@ RUNTIME_FUNCTION(Runtime_FunctionFirstExecution) {
|
||||
function->feedback_vector().ClearOptimizationMarker();
|
||||
// Return the code to continue execution, we don't care at this point whether
|
||||
// this is for lazy compilation or has been eagerly complied.
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
return ToCodeT(function->code());
|
||||
return function->code();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_HealOptimizedCodeSlot) {
|
||||
@ -141,8 +138,7 @@ RUNTIME_FUNCTION(Runtime_HealOptimizedCodeSlot) {
|
||||
function->feedback_vector().EvictOptimizedCodeMarkedForDeoptimization(
|
||||
function->raw_feedback_cell(), function->shared(),
|
||||
"Runtime_HealOptimizedCodeSlot");
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
return ToCodeT(function->code());
|
||||
return function->code();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) {
|
||||
@ -175,8 +171,8 @@ RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) {
|
||||
}
|
||||
shared->set_is_asm_wasm_broken(true);
|
||||
#endif
|
||||
DCHECK_EQ(function->code(), *BUILTIN_CODE(isolate, InstantiateAsmJs));
|
||||
function->set_code(*BUILTIN_CODE(isolate, CompileLazy));
|
||||
DCHECK_EQ(function->code(), *BUILTIN_CODET(isolate, InstantiateAsmJs));
|
||||
function->set_code(*BUILTIN_CODET(isolate, CompileLazy));
|
||||
DCHECK(!isolate->has_pending_exception());
|
||||
return Smi::zero();
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ RUNTIME_FUNCTION(Runtime_IsWasmCode) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_CHECKED(JSFunction, function, 0);
|
||||
Code code = function.code();
|
||||
CodeT code = function.code();
|
||||
bool is_js_to_wasm = code.kind() == CodeKind::JS_TO_WASM_FUNCTION ||
|
||||
(code.builtin_id() == Builtin::kGenericJSToWasmWrapper);
|
||||
return isolate->heap()->ToBoolean(is_js_to_wasm);
|
||||
|
@ -322,7 +322,7 @@ Object OptimizeFunctionOnNextCall(RuntimeArguments& args, Isolate* isolate,
|
||||
// function has.
|
||||
if (!function->is_compiled()) {
|
||||
DCHECK(function->shared().IsInterpreted());
|
||||
function->set_code(*BUILTIN_CODE(isolate, InterpreterEntryTrampoline));
|
||||
function->set_code(*BUILTIN_CODET(isolate, InterpreterEntryTrampoline));
|
||||
}
|
||||
|
||||
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
|
||||
@ -628,7 +628,7 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
|
||||
}
|
||||
|
||||
if (function->HasAttachedOptimizedCode()) {
|
||||
Code code = function->code();
|
||||
CodeT code = function->code();
|
||||
if (code.marked_for_deoptimization()) {
|
||||
status |= static_cast<int>(OptimizationStatus::kMarkedForDeoptimization);
|
||||
} else {
|
||||
|
@ -300,7 +300,7 @@ void Snapshot::ClearReconstructableDataForSerialization(
|
||||
|
||||
// Also, clear out feedback vectors and recompilable code.
|
||||
if (fun.CanDiscardCompiled()) {
|
||||
fun.set_code(*BUILTIN_CODE(isolate, CompileLazy));
|
||||
fun.set_code(*BUILTIN_CODET(isolate, CompileLazy));
|
||||
}
|
||||
if (!fun.raw_feedback_cell(cage_base).value(cage_base).IsUndefined()) {
|
||||
fun.raw_feedback_cell(cage_base).set_value(
|
||||
|
@ -408,7 +408,7 @@ void StringStream::PrintSecurityTokenIfChanged(JSFunction fun) {
|
||||
|
||||
void StringStream::PrintFunction(JSFunction fun, Object receiver, Code* code) {
|
||||
PrintPrototype(fun, receiver);
|
||||
*code = fun.code();
|
||||
*code = FromCodeT(fun.code());
|
||||
}
|
||||
|
||||
void StringStream::PrintPrototype(JSFunction fun, Object receiver) {
|
||||
|
@ -1843,7 +1843,7 @@ uint32_t WasmExceptionPackage::GetEncodedSize(const wasm::WasmTag* tag) {
|
||||
bool WasmExportedFunction::IsWasmExportedFunction(Object object) {
|
||||
if (!object.IsJSFunction()) return false;
|
||||
JSFunction js_function = JSFunction::cast(object);
|
||||
Code code = js_function.code();
|
||||
CodeT code = js_function.code();
|
||||
if (CodeKind::JS_TO_WASM_FUNCTION != code.kind() &&
|
||||
code.builtin_id() != Builtin::kGenericJSToWasmWrapper &&
|
||||
code.builtin_id() != Builtin::kWasmReturnPromiseOnSuspend) {
|
||||
|
@ -20,13 +20,13 @@ std::string DisassembleFunction(const char* function) {
|
||||
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
|
||||
CcTest::global()->Get(context, v8_str(function)).ToLocalChecked())));
|
||||
|
||||
Address begin = f->code().raw_instruction_start();
|
||||
Address end = f->code().raw_instruction_end();
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Handle<Code> code(FromCodeT(f->code()), isolate);
|
||||
Address begin = code->raw_instruction_start();
|
||||
Address end = code->raw_instruction_end();
|
||||
std::ostringstream os;
|
||||
Disassembler::Decode(isolate, os, reinterpret_cast<byte*>(begin),
|
||||
reinterpret_cast<byte*>(end),
|
||||
CodeReference(handle(f->code(), isolate)));
|
||||
reinterpret_cast<byte*>(end), CodeReference(code));
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
@ -3995,8 +3995,7 @@ TEST(EnsureAllocationSiteDependentCodesProcessed) {
|
||||
CHECK_EQ(dependency.length(), DependentCode::kSlotsPerEntry);
|
||||
MaybeObject code = dependency.Get(0 + DependentCode::kCodeSlotOffset);
|
||||
CHECK(code->IsWeak());
|
||||
CHECK_EQ(bar_handle->code(),
|
||||
FromCodeT(CodeT::cast(code->GetHeapObjectAssumeWeak())));
|
||||
CHECK_EQ(bar_handle->code(), CodeT::cast(code->GetHeapObjectAssumeWeak()));
|
||||
Smi groups = dependency.Get(0 + DependentCode::kGroupsSlotOffset).ToSmi();
|
||||
CHECK_EQ(static_cast<DependentCode::DependencyGroups>(groups.value()),
|
||||
DependentCode::kAllocationSiteTransitionChangedGroup |
|
||||
@ -4149,7 +4148,8 @@ TEST(CellsInOptimizedCodeAreWeak) {
|
||||
*v8::Local<v8::Function>::Cast(CcTest::global()
|
||||
->Get(context.local(), v8_str("bar"))
|
||||
.ToLocalChecked())));
|
||||
code = scope.CloseAndEscape(Handle<Code>(bar->code(), isolate));
|
||||
code = handle(FromCodeT(bar->code()), isolate);
|
||||
code = scope.CloseAndEscape(code);
|
||||
}
|
||||
|
||||
// Now make sure that a gc should get rid of the function
|
||||
@ -4193,7 +4193,8 @@ TEST(ObjectsInOptimizedCodeAreWeak) {
|
||||
*v8::Local<v8::Function>::Cast(CcTest::global()
|
||||
->Get(context.local(), v8_str("bar"))
|
||||
.ToLocalChecked())));
|
||||
code = scope.CloseAndEscape(Handle<Code>(bar->code(), isolate));
|
||||
code = handle(FromCodeT(bar->code()), isolate);
|
||||
code = scope.CloseAndEscape(code);
|
||||
}
|
||||
|
||||
// Now make sure that a gc should get rid of the function
|
||||
@ -4255,7 +4256,8 @@ TEST(NewSpaceObjectsInOptimizedCode) {
|
||||
CcTest::heap()->Verify();
|
||||
#endif
|
||||
CHECK(!bar->code().marked_for_deoptimization());
|
||||
code = scope.CloseAndEscape(Handle<Code>(bar->code(), isolate));
|
||||
code = handle(FromCodeT(bar->code()), isolate);
|
||||
code = scope.CloseAndEscape(code);
|
||||
}
|
||||
|
||||
// Now make sure that a gc should get rid of the function
|
||||
@ -4299,7 +4301,8 @@ TEST(ObjectsInEagerlyDeoptimizedCodeAreWeak) {
|
||||
*v8::Local<v8::Function>::Cast(CcTest::global()
|
||||
->Get(context.local(), v8_str("bar"))
|
||||
.ToLocalChecked())));
|
||||
code = scope.CloseAndEscape(Handle<Code>(bar->code(), isolate));
|
||||
code = handle(FromCodeT(bar->code()), isolate);
|
||||
code = scope.CloseAndEscape(code);
|
||||
}
|
||||
|
||||
CHECK(code->marked_for_deoptimization());
|
||||
@ -4361,10 +4364,11 @@ TEST(NextCodeLinkIsWeak) {
|
||||
OptimizeDummyFunction(CcTest::isolate(), "mortal");
|
||||
Handle<JSFunction> immortal =
|
||||
OptimizeDummyFunction(CcTest::isolate(), "immortal");
|
||||
CHECK_EQ(immortal->code().next_code_link(), ToCodeT(mortal->code()));
|
||||
code_chain_length_before = GetCodeChainLength(immortal->code());
|
||||
CHECK_EQ(immortal->code().next_code_link(), mortal->code());
|
||||
code_chain_length_before = GetCodeChainLength(FromCodeT(immortal->code()));
|
||||
// Keep the immortal code and let the mortal code die.
|
||||
code = scope.CloseAndEscape(Handle<Code>(immortal->code(), isolate));
|
||||
code = handle(FromCodeT(immortal->code()), isolate);
|
||||
code = scope.CloseAndEscape(code);
|
||||
CompileRun("mortal = null; immortal = null;");
|
||||
}
|
||||
CcTest::CollectAllAvailableGarbage();
|
||||
@ -4390,9 +4394,10 @@ TEST(NextCodeLinkInCodeDataContainerIsCleared) {
|
||||
OptimizeDummyFunction(CcTest::isolate(), "mortal1");
|
||||
Handle<JSFunction> mortal2 =
|
||||
OptimizeDummyFunction(CcTest::isolate(), "mortal2");
|
||||
CHECK_EQ(mortal2->code().next_code_link(), ToCodeT(mortal1->code()));
|
||||
code_data_container = scope.CloseAndEscape(Handle<CodeDataContainer>(
|
||||
mortal2->code().code_data_container(kAcquireLoad), isolate));
|
||||
CHECK_EQ(mortal2->code().next_code_link(), mortal1->code());
|
||||
code_data_container =
|
||||
handle(CodeDataContainerFromCodeT(mortal2->code()), isolate);
|
||||
code_data_container = scope.CloseAndEscape(code_data_container);
|
||||
CompileRun("mortal1 = null; mortal2 = null;");
|
||||
}
|
||||
CcTest::CollectAllAvailableGarbage();
|
||||
@ -5367,7 +5372,7 @@ static void RemoveCodeAndGC(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
Handle<JSFunction> fun = Handle<JSFunction>::cast(obj);
|
||||
// Bytecode is code too.
|
||||
SharedFunctionInfo::DiscardCompiled(isolate, handle(fun->shared(), isolate));
|
||||
fun->set_code(*BUILTIN_CODE(isolate, CompileLazy));
|
||||
fun->set_code(*BUILTIN_CODET(isolate, CompileLazy));
|
||||
CcTest::CollectAllAvailableGarbage();
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ class InterpreterTester {
|
||||
source += "){})";
|
||||
function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
|
||||
*v8::Local<v8::Function>::Cast(CompileRun(source.c_str()))));
|
||||
function->set_code(*BUILTIN_CODE(isolate_, InterpreterEntryTrampoline));
|
||||
function->set_code(*BUILTIN_CODET(isolate_, InterpreterEntryTrampoline));
|
||||
is_compiled_scope = function->shared().is_compiled_scope(isolate_);
|
||||
}
|
||||
|
||||
|
@ -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(FromCodeT(isolate->factory()
|
||||
->promise_capability_default_resolve_shared_fun()
|
||||
->GetCode()),
|
||||
CHECK_EQ(isolate->factory()
|
||||
->promise_capability_default_resolve_shared_fun()
|
||||
->GetCode(),
|
||||
fun->code());
|
||||
}
|
||||
|
||||
|
@ -4205,7 +4205,7 @@ int GetSourcePositionEntryCount(i::Isolate* isolate, const char* source,
|
||||
i::Handle<i::JSFunction> function = i::Handle<i::JSFunction>::cast(
|
||||
v8::Utils::OpenHandle(*CompileRun(source)));
|
||||
if (function->ActiveTierIsIgnition()) return -1;
|
||||
i::Handle<i::Code> code(function->code(), isolate);
|
||||
i::Handle<i::Code> code(i::FromCodeT(function->code()), isolate);
|
||||
i::SourcePositionTableIterator iterator(
|
||||
ByteArray::cast(code->source_position_table()));
|
||||
|
||||
|
@ -1821,8 +1821,9 @@ WASM_COMPILED_EXEC_TEST(FunctionRefs) {
|
||||
Handle<WasmInternalFunction>::cast(result_cast_reference)->external(),
|
||||
tester.isolate()));
|
||||
|
||||
CHECK_EQ(cast_function->code().raw_instruction_start(),
|
||||
cast_function_reference->code().raw_instruction_start());
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
CHECK_EQ(FromCodeT(cast_function->code()).raw_instruction_start(),
|
||||
FromCodeT(cast_function_reference->code()).raw_instruction_start());
|
||||
|
||||
tester.CheckResult(test, 1);
|
||||
tester.CheckResult(test_fail_1, 0);
|
||||
|
@ -50,7 +50,7 @@ TEST_F(TestWithNativeContext, AddCodeToEmptyCache) {
|
||||
Isolate* isolate = function->GetIsolate();
|
||||
Handle<NativeContext> native_context(function->native_context(), isolate);
|
||||
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
|
||||
Handle<Code> code(function->code(), isolate);
|
||||
Handle<Code> code(FromCodeT(function->code()), isolate);
|
||||
BytecodeOffset bailout_id(1);
|
||||
OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code,
|
||||
bailout_id);
|
||||
@ -83,7 +83,7 @@ TEST_F(TestWithNativeContext, GrowCodeCache) {
|
||||
Isolate* isolate = function->GetIsolate();
|
||||
Handle<NativeContext> native_context(function->native_context(), isolate);
|
||||
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
|
||||
Handle<Code> code(function->code(), isolate);
|
||||
Handle<Code> code(FromCodeT(function->code()), isolate);
|
||||
|
||||
int bailout_id = 0;
|
||||
for (bailout_id = 0; bailout_id < kInitialEntries; bailout_id++) {
|
||||
@ -126,7 +126,7 @@ TEST_F(TestWithNativeContext, FindCachedEntry) {
|
||||
Isolate* isolate = function->GetIsolate();
|
||||
Handle<NativeContext> native_context(function->native_context(), isolate);
|
||||
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
|
||||
Handle<Code> code(function->code(), isolate);
|
||||
Handle<Code> code(FromCodeT(function->code()), isolate);
|
||||
|
||||
int bailout_id = 0;
|
||||
for (bailout_id = 0; bailout_id < kInitialEntries; bailout_id++) {
|
||||
@ -138,7 +138,7 @@ TEST_F(TestWithNativeContext, FindCachedEntry) {
|
||||
GetSource(&source1, 1);
|
||||
Handle<JSFunction> function1 = RunJS<JSFunction>(source1.begin());
|
||||
Handle<SharedFunctionInfo> shared1(function1->shared(), isolate);
|
||||
Handle<Code> code1(function1->code(), isolate);
|
||||
Handle<Code> code1(FromCodeT(function1->code()), isolate);
|
||||
OSROptimizedCodeCache::AddOptimizedCode(native_context, shared1, code1,
|
||||
BytecodeOffset(bailout_id));
|
||||
|
||||
@ -172,7 +172,7 @@ TEST_F(TestWithNativeContext, MaxCapacityCache) {
|
||||
Isolate* isolate = function->GetIsolate();
|
||||
Handle<NativeContext> native_context(function->native_context(), isolate);
|
||||
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
|
||||
Handle<Code> code(function->code(), isolate);
|
||||
Handle<Code> code(FromCodeT(function->code()), isolate);
|
||||
|
||||
int bailout_id = 0;
|
||||
// Add max_capacity - 1 entries.
|
||||
@ -189,7 +189,7 @@ TEST_F(TestWithNativeContext, MaxCapacityCache) {
|
||||
GetSource(&source1, 1);
|
||||
Handle<JSFunction> function1 = RunJS<JSFunction>(source1.begin());
|
||||
Handle<SharedFunctionInfo> shared1(function1->shared(), isolate);
|
||||
Handle<Code> code1(function1->code(), isolate);
|
||||
Handle<Code> code1(FromCodeT(function1->code()), isolate);
|
||||
OSROptimizedCodeCache::AddOptimizedCode(native_context, shared1, code1,
|
||||
BytecodeOffset(bailout_id));
|
||||
osr_cache = Handle<OSROptimizedCodeCache>(
|
||||
@ -213,7 +213,7 @@ TEST_F(TestWithNativeContext, MaxCapacityCache) {
|
||||
GetSource(&source2, 2);
|
||||
Handle<JSFunction> function2 = RunJS<JSFunction>(source2.begin());
|
||||
Handle<SharedFunctionInfo> shared2(function2->shared(), isolate);
|
||||
Handle<Code> code2(function2->code(), isolate);
|
||||
Handle<Code> code2(FromCodeT(function2->code()), isolate);
|
||||
bailout_id++;
|
||||
OSROptimizedCodeCache::AddOptimizedCode(native_context, shared2, code2,
|
||||
BytecodeOffset(bailout_id));
|
||||
@ -243,7 +243,7 @@ TEST_F(TestWithNativeContext, ReuseClearedEntry) {
|
||||
Isolate* isolate = function->GetIsolate();
|
||||
Handle<NativeContext> native_context(function->native_context(), isolate);
|
||||
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
|
||||
Handle<Code> code(function->code(), isolate);
|
||||
Handle<Code> code(FromCodeT(function->code()), isolate);
|
||||
|
||||
int num_entries = kInitialEntries * 2;
|
||||
int expected_length = kInitialLength * 2;
|
||||
@ -267,7 +267,7 @@ TEST_F(TestWithNativeContext, ReuseClearedEntry) {
|
||||
GetSource(&source1, 1);
|
||||
Handle<JSFunction> function1 = RunJS<JSFunction>(source1.begin());
|
||||
Handle<SharedFunctionInfo> shared1(function1->shared(), isolate);
|
||||
Handle<Code> code1(function1->code(), isolate);
|
||||
Handle<Code> code1(FromCodeT(function1->code()), isolate);
|
||||
OSROptimizedCodeCache::AddOptimizedCode(native_context, shared1, code1,
|
||||
BytecodeOffset(bailout_id));
|
||||
osr_cache = Handle<OSROptimizedCodeCache>(
|
||||
@ -290,7 +290,7 @@ TEST_F(TestWithNativeContext, ReuseClearedEntry) {
|
||||
GetSource(&source2, 2);
|
||||
Handle<JSFunction> function2 = RunJS<JSFunction>(source2.begin());
|
||||
Handle<SharedFunctionInfo> shared2(function2->shared(), isolate);
|
||||
Handle<Code> code2(function2->code(), isolate);
|
||||
Handle<Code> code2(FromCodeT(function2->code()), isolate);
|
||||
bailout_id++;
|
||||
OSROptimizedCodeCache::AddOptimizedCode(native_context, shared2, code2,
|
||||
BytecodeOffset(bailout_id));
|
||||
@ -320,13 +320,13 @@ TEST_F(TestWithNativeContext, EvictDeoptedEntriesNoCompact) {
|
||||
Isolate* isolate = function->GetIsolate();
|
||||
Handle<NativeContext> native_context(function->native_context(), isolate);
|
||||
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
|
||||
Handle<Code> code(function->code(), isolate);
|
||||
Handle<Code> code(FromCodeT(function->code()), isolate);
|
||||
|
||||
base::ScopedVector<char> source1(1024);
|
||||
GetSource(&source1, 1);
|
||||
Handle<JSFunction> deopt_function = RunJS<JSFunction>(source1.begin());
|
||||
Handle<SharedFunctionInfo> deopt_shared(deopt_function->shared(), isolate);
|
||||
Handle<Code> deopt_code(deopt_function->code(), isolate);
|
||||
Handle<Code> deopt_code(FromCodeT(deopt_function->code()), isolate);
|
||||
|
||||
int num_entries = kInitialEntries * 2;
|
||||
int expected_length = kInitialLength * 2;
|
||||
@ -379,13 +379,13 @@ TEST_F(TestWithNativeContext, EvictDeoptedEntriesCompact) {
|
||||
Isolate* isolate = function->GetIsolate();
|
||||
Handle<NativeContext> native_context(function->native_context(), isolate);
|
||||
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
|
||||
Handle<Code> code(function->code(), isolate);
|
||||
Handle<Code> code(FromCodeT(function->code()), isolate);
|
||||
|
||||
base::ScopedVector<char> source1(1024);
|
||||
GetSource(&source1, 1);
|
||||
Handle<JSFunction> deopt_function = RunJS<JSFunction>(source1.begin());
|
||||
Handle<SharedFunctionInfo> deopt_shared(deopt_function->shared(), isolate);
|
||||
Handle<Code> deopt_code(deopt_function->code(), isolate);
|
||||
Handle<Code> deopt_code(FromCodeT(deopt_function->code()), isolate);
|
||||
|
||||
int num_entries = kInitialEntries + 1;
|
||||
int expected_length = kInitialLength * 2;
|
||||
|
Loading…
Reference in New Issue
Block a user