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

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

Issue 14812005: Cleanup deoptimization code to make it architecture independent (in progress). (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 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 FP | <- TOS
335 // +------------------+ 335 // +------------------+
336 // | return-address | (deoptimization point) 336 // | Saved LR | (deoptimization point)
337 // +------------------+ 337 // +------------------+
338 // | optimized frame | 338 // | stub pc marker | (necessary to keep constant offset SP - Saved LR.
339 // +------------------+
340 // | optimized frame | <- SP of optimized code
339 // | ... | 341 // | ... |
340 // 342 //
341 // Parts of the code cannot GC, part of the code can GC. 343 // Parts of the code cannot GC, part of the code can GC.
342 static void GenerateDeoptimizationSequence(Assembler* assembler, 344 static void GenerateDeoptimizationSequence(Assembler* assembler,
343 bool preserve_result) { 345 bool preserve_result) {
344 __ EnterFrame((1 << FP) | (1 << LR), 0); 346 __ EnterStubFrame(); // Do not save pp (implicit saved regs to fp offset).
345 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry 347 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
346 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. 348 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
347 const intptr_t saved_r0_offset_from_fp = -(kNumberOfCpuRegisters - R0); 349 const intptr_t saved_r0_offset_from_fp = -(kNumberOfCpuRegisters - R0);
348 // Result in R0 is preserved as part of pushing all registers below. 350 // Result in R0 is preserved as part of pushing all registers below.
349 351
352 // 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.
354
350 // Push registers in their enumeration order: lowest register number at 355 // Push registers in their enumeration order: lowest register number at
351 // lowest address. 356 // lowest address.
352 __ PushList(kAllCpuRegistersList); 357 __ PushList(kAllCpuRegistersList);
353 ASSERT(kFpuRegisterSize == 2 * kWordSize); 358 ASSERT(kFpuRegisterSize == 2 * kWordSize);
354 __ vstmd(DB_W, SP, D0, static_cast<DRegister>(kNumberOfDRegisters - 1)); 359 __ vstmd(DB_W, SP, D0, static_cast<DRegister>(kNumberOfDRegisters - 1));
355 360
356 __ mov(R0, ShifterOperand(SP)); // Pass address of saved registers block. 361 __ mov(R0, ShifterOperand(SP)); // Pass address of saved registers block.
357 __ ReserveAlignedFrameSpace(0); 362 __ ReserveAlignedFrameSpace(0);
358 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry); 363 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry);
359 // Result (R0) is stack-size (FP - SP) in bytes, incl. the return address. 364 // Result (R0) is stack-size (FP - SP) in bytes, incl. the return address.
360 365
361 if (preserve_result) { 366 if (preserve_result) {
362 // Restore result into R1 temporarily. 367 // Restore result into R1 temporarily.
363 __ ldr(R1, Address(FP, saved_r0_offset_from_fp * kWordSize)); 368 __ ldr(R1, Address(FP, saved_r0_offset_from_fp * kWordSize));
364 } 369 }
365 370
366 __ LeaveFrame((1 << FP) | (1 << LR)); 371 __ LeaveStubFrame(); // Restores FP and LR from stack.
367 __ sub(SP, FP, ShifterOperand(R0)); 372 __ sub(SP, FP, ShifterOperand(R0));
368 373
369 __ EnterFrame((1 << FP) | (1 << LR), 0); 374 __ EnterStubFrame();
370 __ mov(R0, ShifterOperand(SP)); // Get last FP address. 375 __ mov(R0, ShifterOperand(SP)); // Get last FP address.
371 if (preserve_result) { 376 if (preserve_result) {
372 __ Push(R1); // Preserve result. 377 __ Push(R1); // Preserve result.
373 } 378 }
374 __ ReserveAlignedFrameSpace(0); 379 __ ReserveAlignedFrameSpace(0);
375 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in R0. 380 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in R0.
376 // Result (R0) is our FP. 381 // Result (R0) is our FP.
377 if (preserve_result) { 382 if (preserve_result) {
378 // Restore result into R1. 383 // Restore result into R1.
379 __ ldr(R1, Address(FP, -1 * kWordSize)); 384 __ ldr(R1, Address(FP, -1 * kWordSize));
380 } 385 }
381 // Code above cannot cause GC. 386 // Code above cannot cause GC.
382 __ LeaveFrame((1 << FP) | (1 << LR)); 387 __ LeaveStubFrame();
383 __ mov(FP, ShifterOperand(R0)); 388 __ mov(FP, ShifterOperand(R0));
384 389
385 // Frame is fully rewritten at this point and it is safe to perform a GC. 390 // Frame is fully rewritten at this point and it is safe to perform a GC.
386 // Materialize any objects that were deferred by FillFrame because they 391 // Materialize any objects that were deferred by FillFrame because they
387 // require allocation. 392 // require allocation.
388 __ EnterStubFrame(); 393 __ EnterStubFrame();
389 if (preserve_result) { 394 if (preserve_result) {
390 __ Push(R1); // Preserve result, it will be GC-d here. 395 __ Push(R1); // Preserve result, it will be GC-d here.
391 } 396 }
392 __ CallRuntime(kDeoptimizeMaterializeDoublesRuntimeEntry); 397 __ CallRuntime(kDeoptimizeMaterializeDoublesRuntimeEntry);
393 if (preserve_result) { 398 if (preserve_result) {
394 __ Pop(R0); // Restore result. 399 __ Pop(R0); // Restore result.
395 } 400 }
396 __ LeaveStubFrame(); 401 __ LeaveStubFrame();
397 __ Ret(); 402 __ Ret();
398 } 403 }
399 404
400 405
401 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) { 406 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
402 __ Unimplemented("DeoptimizeLazy stub"); 407 // Correct return address to point just after the call that is being
408 // deoptimized.
409 __ AddImmediate(LR, -CallPattern::kFixedLengthInBytes);
410 GenerateDeoptimizationSequence(assembler, true); // Preserve R0.
403 } 411 }
404 412
405 413
406 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 414 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
407 GenerateDeoptimizationSequence(assembler, false); // Don't preserve R0. 415 GenerateDeoptimizationSequence(assembler, false); // Don't preserve R0.
408 } 416 }
409 417
410 418
411 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 419 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
412 __ Unimplemented("MegamorphicMiss stub"); 420 __ Unimplemented("MegamorphicMiss stub");
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after
1902 __ Bind(&reference_compare); 1910 __ Bind(&reference_compare);
1903 __ cmp(left, ShifterOperand(right)); 1911 __ cmp(left, ShifterOperand(right));
1904 __ Bind(&done); 1912 __ Bind(&done);
1905 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); 1913 __ PopList((1 << R0) | (1 << R1) | (1 << R2));
1906 __ Ret(); 1914 __ Ret();
1907 } 1915 }
1908 1916
1909 } // namespace dart 1917 } // namespace dart
1910 1918
1911 #endif // defined TARGET_ARCH_ARM 1919 #endif // defined TARGET_ARCH_ARM
OLDNEW
« runtime/vm/constants_x64.h ('K') | « runtime/vm/intermediate_language_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698