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

Side by Side Diff: runtime/vm/stub_code_x64.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
« runtime/vm/stack_frame_ia32.h ('K') | « runtime/vm/stub_code_ia32.cc ('k') | no next file » | 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) 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_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 } 300 }
301 301
302 302
303 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 303 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
304 intptr_t deopt_reason, 304 intptr_t deopt_reason,
305 uword saved_registers_address); 305 uword saved_registers_address);
306 306
307 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); 307 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp);
308 308
309 309
310 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary.
310 // This stub translates optimized frame into unoptimized frame. The optimized 311 // This stub translates optimized frame into unoptimized frame. The optimized
311 // frame can contain values in registers and on stack, the unoptimized 312 // frame can contain values in registers and on stack, the unoptimized
312 // frame contains all values on stack. 313 // frame contains all values on stack.
313 // Deoptimization occurs in following steps: 314 // Deoptimization occurs in following steps:
314 // - Push all registers that can contain values. 315 // - Push all registers that can contain values.
315 // - Call C routine to copy the stack and saved registers into temporary buffer. 316 // - Call C routine to copy the stack and saved registers into temporary buffer.
316 // - Adjust caller's frame to correct unoptimized frame size. 317 // - Adjust caller's frame to correct unoptimized frame size.
317 // - Fill the unoptimized frame. 318 // - Fill the unoptimized frame.
318 // - Materialize objects that require allocation (e.g. Double instances). 319 // - Materialize objects that require allocation (e.g. Double instances).
319 // GC can occur only after frame is fully rewritten. 320 // GC can occur only after frame is fully rewritten.
320 // Stack after EnterFrame(0) below: 321 // Stack after EnterDartFrame(0) below:
321 // +------------------+ 322 // +------------------+
322 // | Saved FP | <- TOS 323 // | PC marker | <- TOS
324 // +------------------+
325 // | Saved FP | <- FP of stub
323 // +------------------+ 326 // +------------------+
324 // | return-address | (deoptimization point) 327 // | return-address | (deoptimization point)
325 // +------------------+ 328 // +------------------+
326 // | optimized frame | 329 // | ... | <- SP of optimized frame
327 // | ... |
328 // 330 //
329 // Parts of the code cannot GC, part of the code can GC. 331 // Parts of the code cannot GC, part of the code can GC.
330 static void GenerateDeoptimizationSequence(Assembler* assembler, 332 static void GenerateDeoptimizationSequence(Assembler* assembler,
331 bool preserve_rax) { 333 bool preserve_result) {
332 __ EnterFrame(0); 334 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
335 __ EnterDartFrame(0);
333 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry 336 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
334 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. 337 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
335 const intptr_t saved_rax_offset_from_ebp = -(kNumberOfCpuRegisters - RAX); 338 const intptr_t saved_result_slot_from_fp =
336 // Result in EAX is preserved as part of pushing all registers below. 339 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - RAX);
340 // Result in RAX is preserved as part of pushing all registers below.
337 341
338 // Push registers in their enumeration order: lowest register number at 342 // Push registers in their enumeration order: lowest register number at
339 // lowest address. 343 // lowest address.
340 for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) { 344 for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) {
341 __ pushq(static_cast<Register>(i)); 345 __ pushq(static_cast<Register>(i));
342 } 346 }
343 __ subq(RSP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize)); 347 __ subq(RSP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize));
344 intptr_t offset = 0; 348 intptr_t offset = 0;
345 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { 349 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
346 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); 350 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
347 __ movups(Address(RSP, offset), xmm_reg); 351 __ movups(Address(RSP, offset), xmm_reg);
348 offset += kFpuRegisterSize; 352 offset += kFpuRegisterSize;
349 } 353 }
350 354
351 __ movq(RDI, RSP); // Pass address of saved registers block. 355 __ movq(RDI, RSP); // Pass address of saved registers block.
352 __ ReserveAlignedFrameSpace(0); 356 __ ReserveAlignedFrameSpace(0);
353 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry); 357 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry);
354 // Result (RAX) is stack-size (FP - SP) in bytes, incl. the return address. 358 // Result (RAX) is stack-size (FP - SP) in bytes.
355 359
356 if (preserve_rax) { 360 if (preserve_result) {
357 // Restore result into RBX temporarily. 361 // Restore result into RBX temporarily.
358 __ movq(RBX, Address(RBP, saved_rax_offset_from_ebp * kWordSize)); 362 __ movq(RBX, Address(RBP, saved_result_slot_from_fp * kWordSize));
359 } 363 }
360 364
361 __ LeaveFrame(); 365 __ LeaveFrame();
362 __ popq(RCX); // Preserve return address. 366 __ popq(RCX); // Preserve return address.
363 __ movq(RSP, RBP); 367 __ movq(RSP, RBP); // Discard optimized frame.
364 __ subq(RSP, RAX); 368 __ subq(RSP, RAX); // Reserve space for deoptimized frame.
365 __ movq(Address(RSP, 0), RCX); 369 __ pushq(RCX); // Restore return address.
366 370
367 __ EnterFrame(0); 371 // Leaf runtime function DeoptimizeFillFrame expects a Dart frame.
368 __ movq(RCX, RSP); // Get last FP address. 372 __ EnterDartFrame(0);
369 if (preserve_rax) { 373 if (preserve_result) {
370 __ pushq(RBX); // Preserve result. 374 __ pushq(RBX); // Preserve result as first local.
371 } 375 }
372 __ ReserveAlignedFrameSpace(0); 376 __ ReserveAlignedFrameSpace(0);
373 __ movq(RDI, RCX); // Set up argument 1 last_fp. 377 __ movq(RDI, RBP); // Pass last FP as parameter in RDI.
374 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); 378 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry);
375 // Result (RAX) is our FP. 379 if (preserve_result) {
376 if (preserve_rax) {
377 // Restore result into RBX. 380 // Restore result into RBX.
378 __ movq(RBX, Address(RBP, -1 * kWordSize)); 381 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize));
379 } 382 }
380 // Code above cannot cause GC. 383 // Code above cannot cause GC.
381 __ LeaveFrame(); 384 __ LeaveFrame();
382 __ movq(RBP, RAX);
383 385
384 // Frame is fully rewritten at this point and it is safe to perform a GC. 386 // Frame is fully rewritten at this point and it is safe to perform a GC.
385 // Materialize any objects that were deferred by FillFrame because they 387 // Materialize any objects that were deferred by FillFrame because they
386 // require allocation. 388 // require allocation.
387 __ EnterStubFrame(); 389 __ EnterStubFrame();
388 if (preserve_rax) { 390 if (preserve_result) {
389 __ pushq(RBX); // Preserve result, it will be GC-d here. 391 __ pushq(RBX); // Preserve result, it will be GC-d here.
390 } 392 }
391 __ pushq(Immediate(Smi::RawValue(0))); // Space for the result. 393 __ pushq(Immediate(Smi::RawValue(0))); // Space for the result.
392 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry); 394 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry);
393 // Result tells stub how many bytes to remove from the expression stack 395 // Result tells stub how many bytes to remove from the expression stack
394 // of the bottom-most frame. They were used as materialization arguments. 396 // of the bottom-most frame. They were used as materialization arguments.
395 __ popq(RBX); 397 __ popq(RBX);
396 __ SmiUntag(RBX); 398 __ SmiUntag(RBX);
397 if (preserve_rax) { 399 if (preserve_result) {
398 __ popq(RAX); // Restore result. 400 __ popq(RAX); // Restore result.
399 } 401 }
400 __ LeaveFrame(); 402 __ LeaveFrame();
401 403
402 __ popq(RCX); // Pop return address. 404 __ popq(RCX); // Pop return address.
403 __ addq(RSP, RBX); // Remove materialization arguments. 405 __ addq(RSP, RBX); // Remove materialization arguments.
404 __ pushq(RCX); // Push return address. 406 __ pushq(RCX); // Push return address.
405 __ ret(); 407 __ ret();
406 } 408 }
407 409
(...skipping 1682 matching lines...) Expand 10 before | Expand all | Expand 10 after
2090 __ cmpq(left, right); 2092 __ cmpq(left, right);
2091 __ Bind(&done); 2093 __ Bind(&done);
2092 __ popq(right); 2094 __ popq(right);
2093 __ popq(left); 2095 __ popq(left);
2094 __ ret(); 2096 __ ret();
2095 } 2097 }
2096 2098
2097 } // namespace dart 2099 } // namespace dart
2098 2100
2099 #endif // defined TARGET_ARCH_X64 2101 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/stack_frame_ia32.h ('K') | « runtime/vm/stub_code_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698