OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 // Move registers, constants, and copies to memory. Perform moves | 307 // Move registers, constants, and copies to memory. Perform moves |
308 // from the top downward in the frame in order to leave the backing | 308 // from the top downward in the frame in order to leave the backing |
309 // stores of copies in registers. | 309 // stores of copies in registers. |
310 // | 310 // |
311 // Moving memory-backed copies to memory requires a spare register | 311 // Moving memory-backed copies to memory requires a spare register |
312 // for the memory-to-memory moves. Since we are performing a merge, | 312 // for the memory-to-memory moves. Since we are performing a merge, |
313 // we use esi (which is already saved in the frame). We keep track | 313 // we use esi (which is already saved in the frame). We keep track |
314 // of the index of the frame element esi is caching or kIllegalIndex | 314 // of the index of the frame element esi is caching or kIllegalIndex |
315 // if esi has not been disturbed. | 315 // if esi has not been disturbed. |
316 int esi_caches = kIllegalIndex; | 316 int esi_caches = kIllegalIndex; |
317 // A "singleton" memory element. | |
318 FrameElement memory_element = FrameElement::MemoryElement(); | |
319 // Loop downward from the stack pointer or the top of the frame if | 317 // Loop downward from the stack pointer or the top of the frame if |
320 // the stack pointer is floating above the frame. | 318 // the stack pointer is floating above the frame. |
321 int start = Min(static_cast<int>(stack_pointer_), elements_.length() - 1); | 319 int start = Min(static_cast<int>(stack_pointer_), elements_.length() - 1); |
322 for (int i = start; i >= 0; i--) { | 320 for (int i = start; i >= 0; i--) { |
323 FrameElement target = expected->elements_[i]; | 321 FrameElement target = expected->elements_[i]; |
324 if (target.is_memory()) { | 322 if (target.is_memory()) { |
325 FrameElement source = elements_[i]; | 323 FrameElement source = elements_[i]; |
326 switch (source.type()) { | 324 switch (source.type()) { |
327 case FrameElement::INVALID: | 325 case FrameElement::INVALID: |
328 // Not a legal merge move. | 326 // Not a legal merge move. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 __ mov(esi, Operand(ebp, fp_relative(backing_index))); | 361 __ mov(esi, Operand(ebp, fp_relative(backing_index))); |
364 } | 362 } |
365 __ mov(Operand(ebp, fp_relative(i)), esi); | 363 __ mov(Operand(ebp, fp_relative(i)), esi); |
366 } else { | 364 } else { |
367 ASSERT(backing_element.is_register()); | 365 ASSERT(backing_element.is_register()); |
368 __ mov(Operand(ebp, fp_relative(i)), backing_element.reg()); | 366 __ mov(Operand(ebp, fp_relative(i)), backing_element.reg()); |
369 } | 367 } |
370 } | 368 } |
371 break; | 369 break; |
372 } | 370 } |
373 elements_[i] = memory_element; | 371 elements_[i] = target; |
374 } | 372 } |
375 } | 373 } |
376 | 374 |
377 if (esi_caches != kIllegalIndex) { | 375 if (esi_caches != kIllegalIndex) { |
378 __ mov(esi, Operand(ebp, fp_relative(context_index()))); | 376 __ mov(esi, Operand(ebp, fp_relative(context_index()))); |
379 } | 377 } |
380 } | 378 } |
381 | 379 |
382 | 380 |
383 void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) { | 381 void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) { |
384 // We have already done X-to-memory moves. | 382 // We have already done X-to-memory moves. |
385 ASSERT(stack_pointer_ >= expected->stack_pointer_); | 383 ASSERT(stack_pointer_ >= expected->stack_pointer_); |
386 | 384 |
387 for (int i = 0; i < kNumRegisters; i++) { | 385 for (int i = 0; i < kNumRegisters; i++) { |
388 // Move the right value into register i if it is currently in a register. | 386 // Move the right value into register i if it is currently in a register. |
389 int index = expected->register_locations_[i]; | 387 int index = expected->register_locations_[i]; |
390 int use_index = register_locations_[i]; | 388 int use_index = register_locations_[i]; |
391 // Fast check if register is unused in target or already correct | 389 // Skip if register i is unused in the target or else if source is |
392 if (index != kIllegalIndex | 390 // not a register (this is not a register-to-register move). |
393 && index != use_index | 391 if (index == kIllegalIndex || !elements_[index].is_register()) continue; |
394 && elements_[index].is_register()) { | 392 |
395 Register source = elements_[index].reg(); | 393 Register target = { i }; |
396 Register target = { i }; | 394 Register source = elements_[index].reg(); |
| 395 |
| 396 if (index != use_index) { |
397 if (use_index == kIllegalIndex) { // Target is currently unused. | 397 if (use_index == kIllegalIndex) { // Target is currently unused. |
398 // Copy contents of source from source to target. | 398 // Copy contents of source from source to target. |
399 // Set frame element register to target. | 399 // Set frame element register to target. |
400 elements_[index].set_reg(target); | |
401 Use(target, index); | 400 Use(target, index); |
402 Unuse(source); | 401 Unuse(source); |
403 __ mov(target, source); | 402 __ mov(target, source); |
404 } else { | 403 } else { |
405 // Exchange contents of registers source and target. | 404 // Exchange contents of registers source and target. |
| 405 // Nothing except the register backing use_index has changed. |
406 elements_[use_index].set_reg(source); | 406 elements_[use_index].set_reg(source); |
407 elements_[index].set_reg(target); | |
408 register_locations_[target.code()] = index; | 407 register_locations_[target.code()] = index; |
409 register_locations_[source.code()] = use_index; | 408 register_locations_[source.code()] = use_index; |
410 __ xchg(source, target); | 409 __ xchg(source, target); |
411 } | 410 } |
412 } | 411 } |
| 412 |
| 413 if (!elements_[index].is_synced() && |
| 414 expected->elements_[index].is_synced()) { |
| 415 __ mov(Operand(ebp, fp_relative(index)), target); |
| 416 } |
| 417 elements_[index] = expected->elements_[index]; |
413 } | 418 } |
414 } | 419 } |
415 | 420 |
416 | 421 |
417 void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame* expected) { | 422 void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame* expected) { |
418 // Move memory, constants, and copies to registers. This is the | 423 // Move memory, constants, and copies to registers. This is the |
419 // final step and is done from the bottom up so that the backing | 424 // final step and is done from the bottom up so that the backing |
420 // elements of copies are in their correct locations when we | 425 // elements of copies are in their correct locations when we |
421 // encounter the copies. | 426 // encounter the copies. |
422 for (int i = 0; i < kNumRegisters; i++) { | 427 for (int i = 0; i < kNumRegisters; i++) { |
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1121 ASSERT(stack_pointer_ == elements_.length() - 1); | 1126 ASSERT(stack_pointer_ == elements_.length() - 1); |
1122 elements_.Add(FrameElement::MemoryElement()); | 1127 elements_.Add(FrameElement::MemoryElement()); |
1123 stack_pointer_++; | 1128 stack_pointer_++; |
1124 __ push(immediate); | 1129 __ push(immediate); |
1125 } | 1130 } |
1126 | 1131 |
1127 | 1132 |
1128 #undef __ | 1133 #undef __ |
1129 | 1134 |
1130 } } // namespace v8::internal | 1135 } } // namespace v8::internal |
OLD | NEW |