Flutter Engine
The Flutter Engine
pending_deopts.cc
Go to the documentation of this file.
1// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/pending_deopts.h"
6#include "vm/log.h"
7#include "vm/stack_frame.h"
8#include "vm/stub_code.h"
9
10namespace dart {
11
12DECLARE_FLAG(bool, trace_deoptimization);
13
15 : pending_deopts_(new MallocGrowableArray<PendingLazyDeopt>()) {}
17 delete pending_deopts_;
18 pending_deopts_ = nullptr;
19}
20
22 // GrowableArray::Add is not atomic and may be interrupted by a profiler
23 // stack walk.
24 MallocGrowableArray<PendingLazyDeopt>* old_pending_deopts = pending_deopts_;
25 MallocGrowableArray<PendingLazyDeopt>* new_pending_deopts =
26 new MallocGrowableArray<PendingLazyDeopt>(old_pending_deopts->length() +
27 1);
28 for (intptr_t i = 0; i < old_pending_deopts->length(); i++) {
29 ASSERT((*old_pending_deopts)[i].fp() != fp);
30 new_pending_deopts->Add((*old_pending_deopts)[i]);
31 }
32 PendingLazyDeopt deopt(fp, pc);
33 new_pending_deopts->Add(deopt);
34
35 pending_deopts_ = new_pending_deopts;
36 delete old_pending_deopts;
37}
38
39PendingLazyDeopt* PendingDeopts::FindPendingDeoptRecord(uword fp) {
40 for (intptr_t i = 0; i < pending_deopts_->length(); i++) {
41 if ((*pending_deopts_)[i].fp() == fp) {
42 return &(*pending_deopts_)[i];
43 }
44 }
45 return nullptr;
46}
47
49 auto record = FindPendingDeoptRecord(fp);
50 if (record != nullptr) {
51 return record->pc();
52 }
53 FATAL("Missing pending deopt entry");
54 return 0;
55}
56
58 for (intptr_t i = pending_deopts_->length() - 1; i >= 0; i--) {
59 if ((*pending_deopts_)[i].fp() < fp) {
60 if (FLAG_trace_deoptimization) {
61 switch (reason) {
64 "Lazy deopt skipped due to throw for "
65 "fp=%" Pp ", pc=%" Pp "\n",
66 (*pending_deopts_)[i].fp(), (*pending_deopts_)[i].pc());
67 break;
69 THR_Print("Lazy deopt fp=%" Pp " pc=%" Pp "\n",
70 (*pending_deopts_)[i].fp(), (*pending_deopts_)[i].pc());
71 break;
72 }
73 }
74 pending_deopts_->RemoveAt(i);
75 }
76 }
77}
78
81}
82
84 uword frame_pointer,
85 bool* clear_deopt) {
86 *clear_deopt = false;
87
88 // Do not attempt to deopt at async exception handler as it doesn't
89 // belong to the function code. Async handler never continues execution
90 // in the same frame - it either rethrows exception to the caller or
91 // tail calls Dart handler, leaving the function frame before the call.
92 if (program_counter == StubCode::AsyncExceptionHandler().EntryPoint()) {
93 *clear_deopt = true;
94 return program_counter;
95 }
96
97 // Check if the target frame is scheduled for lazy deopt.
98 if (FindPendingDeoptRecord(frame_pointer) != nullptr) {
99#if defined(DEBUG)
100 // Ensure the frame references optimized code.
101 ObjectPtr pc_marker = *(reinterpret_cast<ObjectPtr*>(
102 frame_pointer + runtime_frame_layout.code_from_fp * kWordSize));
103 Code& code = Code::Handle(Code::RawCast(pc_marker));
104 ASSERT(code.is_optimized() && !code.is_force_optimized());
105#endif
106 if (FLAG_trace_deoptimization) {
107 THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n",
108 frame_pointer);
109 }
110 return StubCode::DeoptimizeLazyFromThrow().EntryPoint();
111 }
112
113 return program_counter;
114}
115
116} // namespace dart
void Add(const T &value)
intptr_t length() const
static Object & Handle()
Definition: object.h:407
static ObjectPtr RawCast(ObjectPtr obj)
Definition: object.h:325
uword FindPendingDeopt(uword fp)
void ClearPendingDeoptsBelow(uword fp, ClearReason reason)
void ClearPendingDeoptsAtOrBelow(uword fp, ClearReason reason)
uword RemapExceptionPCForDeopt(uword program_counter, uword frame_pointer, bool *clear_deopt)
void AddPendingDeopt(uword fp, uword pc)
#define THR_Print(format,...)
Definition: log.h:20
#define ASSERT(E)
#define FATAL(error)
Definition: dart_vm.cc:33
uintptr_t uword
Definition: globals.h:501
const uint32_t fp
FrameLayout runtime_frame_layout
Definition: stack_frame.cc:81
constexpr intptr_t kWordSize
Definition: globals.h:509
DECLARE_FLAG(bool, show_invisible_frames)
#define Pp
Definition: globals.h:425
intptr_t code_from_fp
Definition: frame_layout.h:52