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

[ext-code-space] Update frame-related logic for Code-less builtins

Bug: v8:11880
Change-Id: I4515f98ade8237ac049e782b1b886a2139295b3b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3827863Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Reviewed-by: 's avatarJakob Linke <jgruber@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82490}
parent fb8bda3a
......@@ -300,8 +300,6 @@ void Compiler::LogFunctionCompilation(Isolate* isolate,
DCHECK(!abstract_code.is_null());
DCHECK(!abstract_code.is_identical_to(BUILTIN_CODE(isolate, CompileLazy)));
if (!V8_REMOVE_BUILTINS_CODE_OBJECTS && V8_EXTERNAL_CODE_SPACE_BOOL) {
// TODO(v8:11880): remove once AbstactCode representing an embedded builtin
// will contain CodeDataContainer.
DCHECK_NE(*abstract_code, FromCodeT(*BUILTIN_CODE(isolate, CompileLazy)));
}
......
......@@ -566,15 +566,6 @@ CodeLookupResult GetContainingCode(Isolate* isolate, Address pc) {
}
} // namespace
Code StackFrame::LookupCode() const {
CodeLookupResult result = GetContainingCode(isolate(), pc());
DCHECK(result.IsFound());
Code code = result.ToCode();
DCHECK_GE(pc(), code.InstructionStart(isolate(), pc()));
DCHECK_LT(pc(), code.InstructionEnd(isolate(), pc()));
return code;
}
CodeLookupResult StackFrame::LookupCodeT() const {
CodeLookupResult result = GetContainingCode(isolate(), pc());
if (DEBUG_BOOL) {
......@@ -597,7 +588,14 @@ CodeLookupResult StackFrame::LookupCodeT() const {
void StackFrame::IteratePc(RootVisitor* v, Address* pc_address,
Address* constant_pool_address,
CodeLookupResult lookup_result) const {
Code holder = lookup_result.ToCode();
if (lookup_result.IsCodeDataContainer()) {
// The embeded builtins are immovable, so there's no need to update PCs on
// the stack, just visit the CodeT object.
Object code = lookup_result.code_data_container();
v->VisitRunningCode(FullObjectSlot(&code));
return;
}
Code holder = lookup_result.code();
Address old_pc = ReadPC(pc_address);
DCHECK(ReadOnlyHeap::Contains(holder) ||
holder.GetHeap()->GcSafeCodeContains(holder, old_pc));
......@@ -799,8 +797,8 @@ void NativeFrame::ComputeCallerState(State* state) const {
state->constant_pool_address = nullptr;
}
Code EntryFrame::unchecked_code() const {
return FromCodeT(isolate()->builtins()->code(Builtin::kJSEntry));
HeapObject EntryFrame::unchecked_code() const {
return isolate()->builtins()->code(Builtin::kJSEntry);
}
void EntryFrame::ComputeCallerState(State* state) const {
......@@ -821,8 +819,8 @@ StackFrame::Type CWasmEntryFrame::GetCallerState(State* state) const {
}
#endif // V8_ENABLE_WEBASSEMBLY
Code ConstructEntryFrame::unchecked_code() const {
return FromCodeT(isolate()->builtins()->code(Builtin::kJSConstructEntry));
HeapObject ConstructEntryFrame::unchecked_code() const {
return isolate()->builtins()->code(Builtin::kJSConstructEntry);
}
void ExitFrame::ComputeCallerState(State* state) const {
......@@ -1029,9 +1027,9 @@ Object CommonFrame::context() const {
}
int CommonFrame::position() const {
Code code = LookupCode();
CodeLookupResult code = LookupCodeT();
int code_offset = code.GetOffsetFromInstructionStart(isolate(), pc());
return AbstractCode::cast(code).SourcePosition(isolate(), code_offset);
return code.ToAbstractCode().SourcePosition(isolate(), code_offset);
}
int CommonFrame::ComputeExpressionsCount() const {
......@@ -1588,15 +1586,22 @@ void TurbofanFrame::Iterate(RootVisitor* v) const {
IteratePc(v, pc_address(), constant_pool_address(), entry->code);
}
Code StubFrame::unchecked_code() const {
return isolate()->FindCodeObject(pc()).code();
HeapObject StubFrame::unchecked_code() const {
CodeLookupResult code_lookup = isolate()->FindCodeObject(pc());
if (code_lookup.IsCodeDataContainer()) {
return code_lookup.code_data_container();
}
if (code_lookup.IsCode()) {
return code_lookup.code();
}
return {};
}
int StubFrame::LookupExceptionHandlerInTable() {
Code code = LookupCode();
CodeLookupResult code = LookupCodeT();
DCHECK(code.is_turbofanned());
DCHECK_EQ(code.kind(), CodeKind::BUILTIN);
HandlerTable table(code);
HandlerTable table(code.codet());
int pc_offset = code.GetOffsetFromInstructionStart(isolate(), pc());
return table.LookupReturn(pc_offset);
}
......@@ -1615,8 +1620,8 @@ bool JavaScriptFrame::HasInlinedFrames() const {
return functions.size() > 1;
}
Code CommonFrameWithJSLinkage::unchecked_code() const {
return FromCodeT(function().code());
HeapObject CommonFrameWithJSLinkage::unchecked_code() const {
return function().code();
}
int TurbofanFrame::ComputeParametersCount() const {
......@@ -1696,9 +1701,12 @@ Script JavaScriptFrame::script() const {
int CommonFrameWithJSLinkage::LookupExceptionHandlerInTable(
int* stack_depth, HandlerTable::CatchPrediction* prediction) {
DCHECK(!LookupCode().has_handler_table());
DCHECK(!LookupCode().is_optimized_code() ||
LookupCode().kind() == CodeKind::BASELINE);
if (DEBUG_BOOL) {
CodeLookupResult code_lookup_result = LookupCodeT();
CHECK(!code_lookup_result.has_handler_table());
CHECK(!code_lookup_result.is_optimized_code() ||
code_lookup_result.kind() == CodeKind::BASELINE);
}
return -1;
}
......@@ -1753,7 +1761,7 @@ void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args,
code_offset = baseline_frame->GetBytecodeOffset();
abstract_code = AbstractCode::cast(baseline_frame->GetBytecodeArray());
} else {
Code code = frame->unchecked_code();
CodeLookupResult code = frame->LookupCodeT();
code_offset = code.GetOffsetFromInstructionStart(isolate, frame->pc());
}
PrintFunctionAndOffset(function, abstract_code, code_offset, file,
......@@ -2160,7 +2168,7 @@ int TurbofanFrame::LookupExceptionHandlerInTable(
// to use FrameSummary to find the corresponding code offset in unoptimized
// code to perform prediction there.
DCHECK_NULL(prediction);
Code code = LookupCode();
CodeT code = LookupCodeT().ToCodeT();
HandlerTable table(code);
int pc_offset = code.GetOffsetFromInstructionStart(isolate(), pc());
DCHECK_NULL(data); // Data is not used and will not return a value.
......@@ -2180,7 +2188,7 @@ DeoptimizationData OptimizedFrame::GetDeoptimizationData(
DCHECK(is_optimized());
JSFunction opt_function = function();
Code code = FromCodeT(opt_function.code());
CodeT code = 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
......@@ -2189,7 +2197,7 @@ DeoptimizationData OptimizedFrame::GetDeoptimizationData(
CodeLookupResult lookup_result =
isolate()->heap()->GcSafeFindCodeForInnerPointer(pc());
CHECK(lookup_result.IsFound());
code = lookup_result.ToCode();
code = lookup_result.ToCodeT();
}
DCHECK(!code.is_null());
DCHECK(CodeKindCanDeoptimize(code.kind()));
......@@ -2346,13 +2354,14 @@ void InterpretedFrame::PatchBytecodeArray(BytecodeArray bytecode_array) {
}
int BaselineFrame::GetBytecodeOffset() const {
return LookupCode().GetBytecodeOffsetForBaselinePC(this->pc(),
GetBytecodeArray());
Code code = LookupCodeT().code();
return code.GetBytecodeOffsetForBaselinePC(this->pc(), GetBytecodeArray());
}
intptr_t BaselineFrame::GetPCForBytecodeOffset(int bytecode_offset) const {
return LookupCode().GetBaselineStartPCForBytecodeOffset(bytecode_offset,
GetBytecodeArray());
Code code = LookupCodeT().code();
return code.GetBaselineStartPCForBytecodeOffset(bytecode_offset,
GetBytecodeArray());
}
void BaselineFrame::PatchContext(Context value) {
......
......@@ -291,13 +291,15 @@ class StackFrame {
// Get the type of this frame.
virtual Type type() const = 0;
// Get the code associated with this frame.
// This method could be called during marking phase of GC.
virtual Code unchecked_code() const = 0;
// Get the code associated with this frame. The result might be a Code object,
// a CodeT object or an empty value.
// This method is used by Isolate::PushStackTraceAndDie() for collecting a
// stack trace on fatal error and thus it might be called in the middle of GC
// and should be as safe as possible.
virtual HeapObject unchecked_code() const = 0;
// Search for the code associated with this frame.
// TODO(v8:11880): migrate all usages to LookupCodeT().
V8_EXPORT_PRIVATE Code LookupCode() const;
// TODO(v8:11880): rename to LookupCode()
V8_EXPORT_PRIVATE CodeLookupResult LookupCodeT() const;
virtual void Iterate(RootVisitor* v) const = 0;
......@@ -544,7 +546,7 @@ class CommonFrame : public StackFrame {
class TypedFrame : public CommonFrame {
public:
Code unchecked_code() const override { return {}; }
HeapObject unchecked_code() const override { return {}; }
void Iterate(RootVisitor* v) const override;
protected:
......@@ -563,8 +565,7 @@ class CommonFrameWithJSLinkage : public CommonFrame {
Handle<FixedArray> GetParameters() const;
virtual int GetActualArgumentCount() const;
// Determine the code for the frame.
Code unchecked_code() const override;
HeapObject unchecked_code() const override;
// Lookup exception handler for current {pc}, returns -1 if none found. Also
// returns data associated with the handler site specific to the frame type:
......@@ -686,7 +687,7 @@ class EntryFrame : public TypedFrame {
public:
Type type() const override { return ENTRY; }
Code unchecked_code() const override;
HeapObject unchecked_code() const override;
// Garbage collection support.
void Iterate(RootVisitor* v) const override;
......@@ -715,7 +716,7 @@ class ConstructEntryFrame : public EntryFrame {
public:
Type type() const override { return CONSTRUCT_ENTRY; }
Code unchecked_code() const override;
HeapObject unchecked_code() const override;
static ConstructEntryFrame* cast(StackFrame* frame) {
DCHECK(frame->is_construct_entry());
......@@ -799,8 +800,7 @@ class StubFrame : public TypedFrame {
public:
Type type() const override { return STUB; }
// Determine the code for the frame.
Code unchecked_code() const override;
HeapObject unchecked_code() const override;
// Lookup exception handler for current {pc}, returns -1 if none found. Only
// TurboFan stub frames are supported.
......
......@@ -759,16 +759,14 @@ class CallSiteBuilder {
Handle<Object> receiver(combinator->native_context().promise_function(),
isolate_);
// TODO(v8:11880): avoid roundtrips between cdc and code.
Handle<Code> code(FromCodeT(combinator->code()), isolate_);
Handle<CodeT> code(combinator->code(), isolate_);
// TODO(mmarchini) save Promises list from the Promise combinator
Handle<FixedArray> parameters = isolate_->factory()->empty_fixed_array();
// We store the offset of the promise into the element function's
// hash field for element callbacks.
int promise_index =
Smi::ToInt(Smi::cast(element_function->GetIdentityHash())) - 1;
int promise_index = Smi::ToInt(element_function->GetIdentityHash()) - 1;
AppendFrame(receiver, combinator, code, promise_index, flags, parameters);
}
......@@ -1972,7 +1970,7 @@ Object Isolate::UnwindAndFindHandler() {
CHECK(frame->is_java_script());
if (frame->is_turbofan()) {
Code code = frame->LookupCode();
Code code = frame->LookupCodeT().code();
// The debugger triggers lazy deopt for the "to-be-restarted" frame
// immediately when the CDP event arrives while paused.
CHECK(code.marked_for_deoptimization());
......@@ -1995,7 +1993,7 @@ Object Isolate::UnwindAndFindHandler() {
DCHECK(!frame->is_maglev());
debug()->clear_restart_frame();
Code code = FromCodeT(builtins()->code(Builtin::kRestartFrameTrampoline));
CodeT code = *BUILTIN_CODE(this, RestartFrameTrampoline);
return FoundHandler(Context(), code.InstructionStart(), 0,
code.constant_pool(), kNullAddress, frame->fp(),
visited_frames);
......@@ -2011,7 +2009,7 @@ Object Isolate::UnwindAndFindHandler() {
thread_local_top()->handler_ = handler->next_address();
// Gather information from the handler.
Code code = frame->LookupCode();
CodeT code = frame->LookupCodeT().codet();
HandlerTable table(code);
return FoundHandler(Context(), code.InstructionStart(this, frame->pc()),
table.LookupReturn(0), code.constant_pool(),
......@@ -2023,7 +2021,7 @@ Object Isolate::UnwindAndFindHandler() {
case StackFrame::C_WASM_ENTRY: {
StackHandler* handler = frame->top_handler();
thread_local_top()->handler_ = handler->next_address();
Code code = frame->LookupCode();
Code code = frame->LookupCodeT().code();
HandlerTable table(code);
Address instruction_start = code.InstructionStart(this, frame->pc());
int return_offset = static_cast<int>(frame->pc() - instruction_start);
......@@ -2080,9 +2078,10 @@ Object Isolate::UnwindAndFindHandler() {
// For optimized frames we perform a lookup in the handler table.
if (!catchable_by_js) break;
TurbofanFrame* js_frame = static_cast<TurbofanFrame*>(frame);
Code code = frame->LookupCode();
int offset = js_frame->LookupExceptionHandlerInTable(nullptr, nullptr);
if (offset < 0) break;
// The code might be an optimized code or a turbofanned builtin.
CodeT code = frame->LookupCodeT().ToCodeT();
// Compute the stack pointer from the frame pointer. This ensures
// that argument slots on the stack are dropped as returning would.
Address return_sp = frame->fp() +
......@@ -2113,9 +2112,12 @@ Object Isolate::UnwindAndFindHandler() {
wasm::WasmCodeRefScope code_ref_scope;
DCHECK_NULL(wasm::GetWasmCodeManager()->LookupCode(frame->pc()));
#endif // defined(DEBUG) && V8_ENABLE_WEBASSEMBLY
Code code = stub_frame->LookupCode();
if (!code.IsCode() || code.kind() != CodeKind::BUILTIN ||
!code.has_handler_table() || !code.is_turbofanned()) {
// The code might be a dynamically generated stub or a turbofanned
// embedded builtin.
CodeT code = stub_frame->LookupCodeT().ToCodeT();
if (code.kind() != CodeKind::BUILTIN || !code.is_turbofanned() ||
!code.has_handler_table()) {
break;
}
......@@ -2163,20 +2165,20 @@ Object Isolate::UnwindAndFindHandler() {
if (frame->is_baseline()) {
BaselineFrame* sp_frame = BaselineFrame::cast(js_frame);
Code code = sp_frame->LookupCode();
Code code = sp_frame->LookupCodeT().code();
DCHECK(!code.is_off_heap_trampoline());
intptr_t pc_offset = sp_frame->GetPCForBytecodeOffset(offset);
// Patch the context register directly on the frame, so that we don't
// need to have a context read + write in the baseline code.
sp_frame->PatchContext(context);
return FoundHandler(
Context(), code.InstructionStart(this, sp_frame->sp()), pc_offset,
code.constant_pool(), return_sp, sp_frame->fp(), visited_frames);
return FoundHandler(Context(), code.InstructionStart(), pc_offset,
code.constant_pool(), return_sp, sp_frame->fp(),
visited_frames);
} else {
InterpretedFrame::cast(js_frame)->PatchBytecodeOffset(
static_cast<int>(offset));
Code code =
FromCodeT(builtins()->code(Builtin::kInterpreterEnterAtBytecode));
CodeT code = *BUILTIN_CODE(this, InterpreterEnterAtBytecode);
// We subtract a frame from visited_frames because otherwise the
// shadow stack will drop the underlying interpreter entry trampoline
// in which the handler runs.
......@@ -2208,7 +2210,7 @@ Object Isolate::UnwindAndFindHandler() {
// Reconstruct the stack pointer from the frame pointer.
Address return_sp = js_frame->fp() - js_frame->GetSPToFPDelta();
Code code = js_frame->LookupCode();
CodeT code = js_frame->LookupCodeT().codet();
return FoundHandler(Context(), code.InstructionStart(), 0,
code.constant_pool(), return_sp, frame->fp(),
visited_frames);
......@@ -2225,7 +2227,8 @@ Object Isolate::UnwindAndFindHandler() {
USE(removed);
// If there were any materialized objects, the code should be
// marked for deopt.
DCHECK_IMPLIES(removed, frame->LookupCode().marked_for_deoptimization());
DCHECK_IMPLIES(
removed, frame->LookupCodeT().ToCodeT().marked_for_deoptimization());
}
}
......@@ -2247,7 +2250,7 @@ HandlerTable::CatchPrediction PredictException(JavaScriptFrame* frame) {
const FrameSummary& summary = summaries[i - 1];
Handle<AbstractCode> code = summary.AsJavaScript().abstract_code();
if (code->kind(cage_base) == CodeKind::BUILTIN) {
prediction = code->GetCode().GetBuiltinCatchPrediction();
prediction = code->GetBuiltinCatchPrediction(cage_base);
if (prediction == HandlerTable::UNCAUGHT) continue;
return prediction;
}
......@@ -2323,7 +2326,7 @@ Isolate::CatchType Isolate::PredictExceptionCatcher() {
}
case StackFrame::STUB: {
Code code = frame->LookupCode();
CodeLookupResult code = frame->LookupCodeT();
if (code.kind() != CodeKind::BUILTIN || !code.has_handler_table() ||
!code.is_turbofanned()) {
break;
......@@ -2335,7 +2338,7 @@ Isolate::CatchType Isolate::PredictExceptionCatcher() {
}
case StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH: {
Code code = frame->LookupCode();
CodeLookupResult code = frame->LookupCodeT();
CatchType prediction = ToCatchType(code.GetBuiltinCatchPrediction());
if (prediction != NOT_CAUGHT) return prediction;
break;
......@@ -2800,9 +2803,9 @@ Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
if (frame->is_java_script()) {
catch_prediction = PredictException(JavaScriptFrame::cast(frame));
} else if (frame->type() == StackFrame::STUB) {
Code code = frame->LookupCode();
if (!code.IsCode() || code.kind() != CodeKind::BUILTIN ||
!code.has_handler_table() || !code.is_turbofanned()) {
CodeLookupResult code = frame->LookupCodeT();
if (code.kind() != CodeKind::BUILTIN || !code.has_handler_table() ||
!code.is_turbofanned()) {
continue;
}
catch_prediction = code.GetBuiltinCatchPrediction();
......
......@@ -1178,31 +1178,37 @@ class MarkCompactCollector::RootMarkingVisitor final : public RootVisitor {
}
void VisitRunningCode(FullObjectSlot p) final {
Code code = Code::cast(*p);
// If Code is currently executing, then we must not remove its
// deoptimization literals, which it might need in order to successfully
// deoptimize.
//
// Must match behavior in RootsReferencesExtractor::VisitRunningCode, so
// that heap snapshots accurately describe the roots.
if (code.kind() != CodeKind::BASELINE) {
DeoptimizationData deopt_data =
DeoptimizationData::cast(code.deoptimization_data());
if (deopt_data.length() > 0) {
DeoptimizationLiteralArray literals = deopt_data.LiteralArray();
int literals_length = literals.length();
for (int i = 0; i < literals_length; ++i) {
MaybeObject maybe_literal = literals.Get(i);
HeapObject heap_literal;
if (maybe_literal.GetHeapObject(&heap_literal)) {
MarkObjectByPointer(Root::kStackRoots,
FullObjectSlot(&heap_literal));
HeapObject value = HeapObject::cast(*p);
if (V8_EXTERNAL_CODE_SPACE_BOOL && !IsCodeSpaceObject(value)) {
// When external code space is enabled, the slot might contain a CodeT
// object representing an embedded builtin, which doesn't require
// additional processing.
DCHECK(CodeT::cast(value).is_off_heap_trampoline());
} else {
Code code = Code::cast(value);
if (code.kind() != CodeKind::BASELINE) {
DeoptimizationData deopt_data =
DeoptimizationData::cast(code.deoptimization_data());
if (deopt_data.length() > 0) {
DeoptimizationLiteralArray literals = deopt_data.LiteralArray();
int literals_length = literals.length();
for (int i = 0; i < literals_length; ++i) {
MaybeObject maybe_literal = literals.Get(i);
HeapObject heap_literal;
if (maybe_literal.GetHeapObject(&heap_literal)) {
MarkObjectByPointer(Root::kStackRoots,
FullObjectSlot(&heap_literal));
}
}
}
}
}
// And then mark the Code itself.
VisitRootPointer(Root::kStackRoots, nullptr, p);
}
......@@ -2594,7 +2600,10 @@ void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor,
it.Advance()) {
if (it.frame()->is_unoptimized()) return;
if (it.frame()->is_optimized()) {
Code code = it.frame()->LookupCode();
CodeLookupResult lookup_result = it.frame()->LookupCodeT();
// Embedded builtins can't deoptimize.
if (lookup_result.IsCodeDataContainer()) return;
Code code = lookup_result.code();
if (!code.CanDeoptAt(isolate, it.frame()->pc())) {
PtrComprCageBase cage_base(isolate);
Code::BodyDescriptor::IterateBody(code.map(cage_base), code, visitor);
......
......@@ -412,6 +412,8 @@ inline MaybeHandle<CodeT> ToCodeT(MaybeHandle<Code> maybe_code,
inline Code FromCodeT(CodeT code) {
#ifdef V8_EXTERNAL_CODE_SPACE
DCHECK_IMPLIES(V8_REMOVE_BUILTINS_CODE_OBJECTS,
!code.is_off_heap_trampoline());
return code.code();
#else
return code;
......@@ -420,6 +422,8 @@ inline Code FromCodeT(CodeT code) {
inline Code FromCodeT(CodeT code, RelaxedLoadTag) {
#ifdef V8_EXTERNAL_CODE_SPACE
DCHECK_IMPLIES(V8_REMOVE_BUILTINS_CODE_OBJECTS,
!code.is_off_heap_trampoline());
return code.code(kRelaxedLoad);
#else
return code;
......@@ -480,6 +484,7 @@ 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(is_optimized_code, bool)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(stack_slots, int)
CODE_LOOKUP_RESULT_FWD_ACCESSOR(GetBuiltinCatchPrediction,
HandlerTable::CatchPrediction)
......@@ -1505,6 +1510,9 @@ Code CodeDataContainer::code() const {
}
Code CodeDataContainer::code(PtrComprCageBase cage_base) const {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
#ifdef V8_EXTERNAL_CODE_SPACE
DCHECK_IMPLIES(V8_REMOVE_BUILTINS_CODE_OBJECTS, !is_off_heap_trampoline());
#endif
return Code::cast(raw_code(cage_base));
}
......
......@@ -925,6 +925,17 @@ class CodeLookupResult {
#endif
}
// Returns the CodeT object corresponding to the result in question.
// The method doesn't try to convert Code result to CodeT, one should use
// ToCodeT() instead if the conversion logic is required.
CodeT codet() const {
#ifdef V8_EXTERNAL_CODE_SPACE
return code_data_container();
#else
return code();
#endif
}
// 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.
......@@ -937,6 +948,7 @@ class CodeLookupResult {
inline bool is_baseline_leave_frame_builtin() const;
inline bool is_maglevved() const;
inline bool is_turbofanned() const;
inline bool is_optimized_code() const;
inline int stack_slots() const;
inline HandlerTable::CatchPrediction GetBuiltinCatchPrediction() const;
......
......@@ -1990,24 +1990,31 @@ class RootsReferencesExtractor : public RootVisitor {
// Must match behavior in
// MarkCompactCollector::RootMarkingVisitor::VisitRunningCode, which treats
// deoptimization literals in running code as stack roots.
Code code = Code::cast(*p);
if (code.kind() != CodeKind::BASELINE) {
DeoptimizationData deopt_data =
DeoptimizationData::cast(code.deoptimization_data());
if (deopt_data.length() > 0) {
DeoptimizationLiteralArray literals = deopt_data.LiteralArray();
int literals_length = literals.length();
for (int i = 0; i < literals_length; ++i) {
MaybeObject maybe_literal = literals.Get(i);
HeapObject heap_literal;
if (maybe_literal.GetHeapObject(&heap_literal)) {
VisitRootPointer(Root::kStackRoots, nullptr,
FullObjectSlot(&heap_literal));
HeapObject value = HeapObject::cast(*p);
if (V8_EXTERNAL_CODE_SPACE_BOOL && !IsCodeSpaceObject(value)) {
// When external code space is enabled, the slot might contain a CodeT
// object representing an embedded builtin, which doesn't require
// additional processing.
DCHECK(CodeT::cast(value).is_off_heap_trampoline());
} else {
Code code = Code::cast(value);
if (code.kind() != CodeKind::BASELINE) {
DeoptimizationData deopt_data =
DeoptimizationData::cast(code.deoptimization_data());
if (deopt_data.length() > 0) {
DeoptimizationLiteralArray literals = deopt_data.LiteralArray();
int literals_length = literals.length();
for (int i = 0; i < literals_length; ++i) {
MaybeObject maybe_literal = literals.Get(i);
HeapObject heap_literal;
if (maybe_literal.GetHeapObject(&heap_literal)) {
VisitRootPointer(Root::kStackRoots, nullptr,
FullObjectSlot(&heap_literal));
}
}
}
}
}
// Finally visit the Code itself.
VisitRootPointer(Root::kStackRoots, nullptr, p);
}
......
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