| 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 |