Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Side by Side Diff: runtime/vm/exceptions.cc

Issue 2741553002: Do not rely on code patching on DBC for lazy deoptimization. (Closed)
Patch Set: Code review Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/code_patcher_x64.cc ('k') | runtime/vm/instructions_dbc.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/exceptions.h" 5 #include "vm/exceptions.h"
6 6
7 #include "platform/address_sanitizer.h" 7 #include "platform/address_sanitizer.h"
8 8
9 #include "lib/stacktrace.h" 9 #include "lib/stacktrace.h"
10 10
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 ASSERT(frame->IsEntryFrame()); 202 ASSERT(frame->IsEntryFrame());
203 *handler_pc = frame->pc(); 203 *handler_pc = frame->pc();
204 *handler_sp = frame->sp(); 204 *handler_sp = frame->sp();
205 *handler_fp = frame->fp(); 205 *handler_fp = frame->fp();
206 } 206 }
207 207
208 208
209 static uword RemapExceptionPCForDeopt(Thread* thread, 209 static uword RemapExceptionPCForDeopt(Thread* thread,
210 uword program_counter, 210 uword program_counter,
211 uword frame_pointer) { 211 uword frame_pointer) {
212 #if !defined(TARGET_ARCH_DBC)
213 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = 212 MallocGrowableArray<PendingLazyDeopt>* pending_deopts =
214 thread->isolate()->pending_deopts(); 213 thread->isolate()->pending_deopts();
215 if (pending_deopts->length() > 0) { 214 if (pending_deopts->length() > 0) {
216 // Check if the target frame is scheduled for lazy deopt. 215 // Check if the target frame is scheduled for lazy deopt.
217 for (intptr_t i = 0; i < pending_deopts->length(); i++) { 216 for (intptr_t i = 0; i < pending_deopts->length(); i++) {
218 if ((*pending_deopts)[i].fp() == frame_pointer) { 217 if ((*pending_deopts)[i].fp() == frame_pointer) {
219 // Deopt should now resume in the catch handler instead of after the 218 // Deopt should now resume in the catch handler instead of after the
220 // call. 219 // call.
221 (*pending_deopts)[i].set_pc(program_counter); 220 (*pending_deopts)[i].set_pc(program_counter);
222 221
223 // Jump to the deopt stub instead of the catch handler. 222 // Jump to the deopt stub instead of the catch handler.
224 program_counter = 223 program_counter =
225 StubCode::DeoptimizeLazyFromThrow_entry()->EntryPoint(); 224 StubCode::DeoptimizeLazyFromThrow_entry()->EntryPoint();
226 if (FLAG_trace_deoptimization) { 225 if (FLAG_trace_deoptimization) {
227 THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n", 226 THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n",
228 frame_pointer); 227 frame_pointer);
229 } 228 }
230 break; 229 break;
231 } 230 }
232 } 231 }
233 } 232 }
234 #endif // !DBC
235 return program_counter; 233 return program_counter;
236 } 234 }
237 235
238 236
239 static void ClearLazyDeopts(Thread* thread, uword frame_pointer) { 237 static void ClearLazyDeopts(Thread* thread, uword frame_pointer) {
240 #if !defined(TARGET_ARCH_DBC)
241 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = 238 MallocGrowableArray<PendingLazyDeopt>* pending_deopts =
242 thread->isolate()->pending_deopts(); 239 thread->isolate()->pending_deopts();
243 if (pending_deopts->length() > 0) { 240 if (pending_deopts->length() > 0) {
244 // We may be jumping over frames scheduled for lazy deopt. Remove these 241 // We may be jumping over frames scheduled for lazy deopt. Remove these
245 // frames from the pending deopt table, but only after unmarking them so 242 // frames from the pending deopt table, but only after unmarking them so
246 // any stack walk that happens before the stack is unwound will still work. 243 // any stack walk that happens before the stack is unwound will still work.
247 { 244 {
248 DartFrameIterator frames(thread); 245 DartFrameIterator frames(thread);
249 StackFrame* frame = frames.NextFrame(); 246 StackFrame* frame = frames.NextFrame();
250 while ((frame != NULL) && (frame->fp() < frame_pointer)) { 247 while ((frame != NULL) && IsCalleeFrameOf(frame_pointer, frame->fp())) {
251 if (frame->IsMarkedForLazyDeopt()) { 248 if (frame->IsMarkedForLazyDeopt()) {
252 frame->UnmarkForLazyDeopt(); 249 frame->UnmarkForLazyDeopt();
253 } 250 }
254 frame = frames.NextFrame(); 251 frame = frames.NextFrame();
255 } 252 }
256 } 253 }
257 254
258 #if defined(DEBUG) 255 #if defined(DEBUG)
259 ValidateFrames(); 256 ValidateFrames();
260 #endif 257 #endif
261 258
262 for (intptr_t i = 0; i < pending_deopts->length(); i++) { 259 for (intptr_t i = 0; i < pending_deopts->length(); i++) {
263 if ((*pending_deopts)[i].fp() < frame_pointer) { 260 if (IsCalleeFrameOf(frame_pointer, (*pending_deopts)[i].fp())) {
264 if (FLAG_trace_deoptimization) { 261 if (FLAG_trace_deoptimization) {
265 THR_Print( 262 THR_Print(
266 "Lazy deopt skipped due to throw for " 263 "Lazy deopt skipped due to throw for "
267 "fp=%" Pp ", pc=%" Pp "\n", 264 "fp=%" Pp ", pc=%" Pp "\n",
268 (*pending_deopts)[i].fp(), (*pending_deopts)[i].pc()); 265 (*pending_deopts)[i].fp(), (*pending_deopts)[i].pc());
269 } 266 }
270 pending_deopts->RemoveAt(i); 267 pending_deopts->RemoveAt(i);
271 } 268 }
272 } 269 }
273 270
274 #if defined(DEBUG) 271 #if defined(DEBUG)
275 ValidateFrames(); 272 ValidateFrames();
276 #endif 273 #endif
277 } 274 }
278 #endif // !DBC
279 } 275 }
280 276
281 277
282 static void JumpToExceptionHandler(Thread* thread, 278 static void JumpToExceptionHandler(Thread* thread,
283 uword program_counter, 279 uword program_counter,
284 uword stack_pointer, 280 uword stack_pointer,
285 uword frame_pointer, 281 uword frame_pointer,
286 const Object& exception_object, 282 const Object& exception_object,
287 const Object& stacktrace_object) { 283 const Object& stacktrace_object) {
288 uword remapped_pc = 284 uword remapped_pc =
289 RemapExceptionPCForDeopt(thread, program_counter, frame_pointer); 285 RemapExceptionPCForDeopt(thread, program_counter, frame_pointer);
290 thread->set_active_exception(exception_object); 286 thread->set_active_exception(exception_object);
291 thread->set_active_stacktrace(stacktrace_object); 287 thread->set_active_stacktrace(stacktrace_object);
292 thread->set_resume_pc(remapped_pc); 288 thread->set_resume_pc(remapped_pc);
293 uword run_exception_pc = StubCode::RunExceptionHandler_entry()->EntryPoint(); 289 uword run_exception_pc = StubCode::RunExceptionHandler_entry()->EntryPoint();
294 Exceptions::JumpToFrame(thread, run_exception_pc, stack_pointer, 290 Exceptions::JumpToFrame(thread, run_exception_pc, stack_pointer,
295 frame_pointer, false /* do not clear deopt */); 291 frame_pointer, false /* do not clear deopt */);
296 } 292 }
297 293
298 294
299 void Exceptions::JumpToFrame(Thread* thread, 295 void Exceptions::JumpToFrame(Thread* thread,
300 uword program_counter, 296 uword program_counter,
301 uword stack_pointer, 297 uword stack_pointer,
302 uword frame_pointer, 298 uword frame_pointer,
303 bool clear_deopt_at_target) { 299 bool clear_deopt_at_target) {
304 uword fp_for_clearing = 300 uword fp_for_clearing = (clear_deopt_at_target
305 (clear_deopt_at_target ? frame_pointer + 1 : frame_pointer); 301 #if defined(TARGET_ARCH_DBC)
302 ? frame_pointer - 1
303 #else
304 ? frame_pointer + 1
305 #endif
306 : frame_pointer);
306 ClearLazyDeopts(thread, fp_for_clearing); 307 ClearLazyDeopts(thread, fp_for_clearing);
307 #if defined(USING_SIMULATOR) 308 #if defined(USING_SIMULATOR)
308 // Unwinding of the C++ frames and destroying of their stack resources is done 309 // Unwinding of the C++ frames and destroying of their stack resources is done
309 // by the simulator, because the target stack_pointer is a simulated stack 310 // by the simulator, because the target stack_pointer is a simulated stack
310 // pointer and not the C++ stack pointer. 311 // pointer and not the C++ stack pointer.
311 312
312 // Continue simulating at the given pc in the given frame after setting up the 313 // Continue simulating at the given pc in the given frame after setting up the
313 // exception object in the kExceptionObjectReg register and the stacktrace 314 // exception object in the kExceptionObjectReg register and the stacktrace
314 // object (may be raw null) in the kStackTraceObjectReg register. 315 // object (may be raw null) in the kStackTraceObjectReg register.
315 316
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 class_name = &Symbols::_CompileTimeError(); 818 class_name = &Symbols::_CompileTimeError();
818 break; 819 break;
819 } 820 }
820 821
821 return DartLibraryCalls::InstanceCreate(library, *class_name, 822 return DartLibraryCalls::InstanceCreate(library, *class_name,
822 *constructor_name, arguments); 823 *constructor_name, arguments);
823 } 824 }
824 825
825 826
826 } // namespace dart 827 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher_x64.cc ('k') | runtime/vm/instructions_dbc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698