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

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

Issue 15110003: Make deoptimization architecture dependent (it depends on the frame layout). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 // frame contains all values on stack. 324 // frame contains all values on stack.
325 // Deoptimization occurs in following steps: 325 // Deoptimization occurs in following steps:
326 // - Push all registers that can contain values. 326 // - Push all registers that can contain values.
327 // - Call C routine to copy the stack and saved registers into temporary buffer. 327 // - Call C routine to copy the stack and saved registers into temporary buffer.
328 // - Adjust caller's frame to correct unoptimized frame size. 328 // - Adjust caller's frame to correct unoptimized frame size.
329 // - Fill the unoptimized frame. 329 // - Fill the unoptimized frame.
330 // - Materialize objects that require allocation (e.g. Double instances). 330 // - Materialize objects that require allocation (e.g. Double instances).
331 // GC can occur only after frame is fully rewritten. 331 // GC can occur only after frame is fully rewritten.
332 // Stack after EnterFrame(...) below: 332 // Stack after EnterFrame(...) below:
333 // +------------------+ 333 // +------------------+
334 // | Saved FP | <- TOS 334 // | Saved PP | <- TOS
335 // +------------------+
336 // | Saved FP | <- FP of stub
335 // +------------------+ 337 // +------------------+
336 // | Saved LR | (deoptimization point) 338 // | Saved LR | (deoptimization point)
337 // +------------------+ 339 // +------------------+
338 // | stub pc marker | (necessary to keep constant offset SP - Saved LR. 340 // | PC marker |
339 // +------------------+ 341 // +------------------+
340 // | optimized frame | <- SP of optimized code 342 // | ... | <- SP of optimized frame
341 // | ... |
342 // 343 //
343 // Parts of the code cannot GC, part of the code can GC. 344 // Parts of the code cannot GC, part of the code can GC.
344 static void GenerateDeoptimizationSequence(Assembler* assembler, 345 static void GenerateDeoptimizationSequence(Assembler* assembler,
345 bool preserve_result) { 346 bool preserve_result) {
346 __ EnterStubFrame(); // Do not save pp (implicit saved regs to fp offset). 347 // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
348 // is no need to set the correct PC marker or load PP, since they get patched.
349 __ EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0);
347 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry 350 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
348 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. 351 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
349 const intptr_t saved_r0_offset_from_fp = -(kNumberOfCpuRegisters - R0); 352 const intptr_t saved_result_slot_from_fp =
353 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - R0);
350 // Result in R0 is preserved as part of pushing all registers below. 354 // Result in R0 is preserved as part of pushing all registers below.
351 355
352 // TODO(regis): Should we align the stack before pushing the fpu registers? 356 // TODO(regis): Should we align the stack before pushing the fpu registers?
353 // If we do, saved_r0_offset_from_fp is not constant anymore. 357 // If we do, saved_r0_offset_from_fp is not constant anymore.
354 358
355 // Push registers in their enumeration order: lowest register number at 359 // Push registers in their enumeration order: lowest register number at
356 // lowest address. 360 // lowest address.
357 __ PushList(kAllCpuRegistersList); 361 __ PushList(kAllCpuRegistersList);
358 ASSERT(kFpuRegisterSize == 2 * kWordSize); 362 ASSERT(kFpuRegisterSize == 2 * kWordSize);
359 __ vstmd(DB_W, SP, D0, static_cast<DRegister>(kNumberOfDRegisters - 1)); 363 __ vstmd(DB_W, SP, D0, static_cast<DRegister>(kNumberOfDRegisters - 1));
360 364
361 __ mov(R0, ShifterOperand(SP)); // Pass address of saved registers block. 365 __ mov(R0, ShifterOperand(SP)); // Pass address of saved registers block.
362 __ ReserveAlignedFrameSpace(0); 366 __ ReserveAlignedFrameSpace(0);
363 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry); 367 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry);
364 // Result (R0) is stack-size (FP - SP) in bytes, incl. the return address. 368 // Result (R0) is stack-size (FP - SP) in bytes.
365 369
366 if (preserve_result) { 370 if (preserve_result) {
367 // Restore result into R1 temporarily. 371 // Restore result into R1 temporarily.
368 __ ldr(R1, Address(FP, saved_r0_offset_from_fp * kWordSize)); 372 __ ldr(R1, Address(FP, saved_result_slot_from_fp * kWordSize));
369 } 373 }
370 374
371 __ LeaveStubFrame(); // Restores FP and LR from stack. 375 __ LeaveDartFrame();
372 __ sub(SP, FP, ShifterOperand(R0)); 376 __ sub(SP, FP, ShifterOperand(R0));
373 377
374 __ EnterStubFrame(); 378 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
375 __ mov(R0, ShifterOperand(SP)); // Get last FP address. 379 // is no need to set the correct PC marker or load PP, since they get patched.
380 __ EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0);
381 __ mov(R0, ShifterOperand(FP)); // Get last FP address.
376 if (preserve_result) { 382 if (preserve_result) {
377 __ Push(R1); // Preserve result. 383 __ Push(R1); // Preserve result as first local.
378 } 384 }
379 __ ReserveAlignedFrameSpace(0); 385 __ ReserveAlignedFrameSpace(0);
380 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in R0. 386 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in R0.
381 // Result (R0) is our FP.
382 if (preserve_result) { 387 if (preserve_result) {
383 // Restore result into R1. 388 // Restore result into R1.
384 __ ldr(R1, Address(FP, -1 * kWordSize)); 389 __ ldr(R1, Address(FP, kFirstLocalSlotFromFp * kWordSize));
385 } 390 }
386 // Code above cannot cause GC. 391 // Code above cannot cause GC.
387 __ LeaveStubFrame(); 392 __ LeaveDartFrame();
388 __ mov(FP, ShifterOperand(R0));
389 393
390 // Frame is fully rewritten at this point and it is safe to perform a GC. 394 // Frame is fully rewritten at this point and it is safe to perform a GC.
391 // Materialize any objects that were deferred by FillFrame because they 395 // Materialize any objects that were deferred by FillFrame because they
392 // require allocation. 396 // require allocation.
393 __ EnterStubFrame(); 397 __ EnterStubFrame();
394 if (preserve_result) { 398 if (preserve_result) {
395 __ Push(R1); // Preserve result, it will be GC-d here. 399 __ Push(R1); // Preserve result, it will be GC-d here.
396 } 400 }
397 __ PushObject(Smi::ZoneHandle()); // Space for the result. 401 __ PushObject(Smi::ZoneHandle()); // Space for the result.
398 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry); 402 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry);
(...skipping 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after
1937 __ Bind(&reference_compare); 1941 __ Bind(&reference_compare);
1938 __ cmp(left, ShifterOperand(right)); 1942 __ cmp(left, ShifterOperand(right));
1939 __ Bind(&done); 1943 __ Bind(&done);
1940 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); 1944 __ PopList((1 << R0) | (1 << R1) | (1 << R2));
1941 __ Ret(); 1945 __ Ret();
1942 } 1946 }
1943 1947
1944 } // namespace dart 1948 } // namespace dart
1945 1949
1946 #endif // defined TARGET_ARCH_ARM 1950 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698