| OLD | NEW |
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 | 212 |
| 213 // Clear the dirty bits for the range of elements in [begin, end). | 213 // Clear the dirty bits for the range of elements in [begin, end). |
| 214 void VirtualFrame::SyncRange(int begin, int end) { | 214 void VirtualFrame::SyncRange(int begin, int end) { |
| 215 ASSERT(begin >= 0); | 215 ASSERT(begin >= 0); |
| 216 ASSERT(end <= elements_.length()); | 216 ASSERT(end <= elements_.length()); |
| 217 for (int i = begin; i < end; i++) { | 217 for (int i = begin; i < end; i++) { |
| 218 SyncElementAt(i); | 218 SyncElementAt(i); |
| 219 } | 219 } |
| 220 } | 220 } |
| 221 | 221 |
| 222 |
| 222 // Make the type of all elements be MEMORY. | 223 // Make the type of all elements be MEMORY. |
| 223 void VirtualFrame::SpillAll() { | 224 void VirtualFrame::SpillAll() { |
| 224 for (int i = 0; i < elements_.length(); i++) { | 225 for (int i = 0; i < elements_.length(); i++) { |
| 225 SpillElementAt(i); | 226 SpillElementAt(i); |
| 226 } | 227 } |
| 227 } | 228 } |
| 228 | 229 |
| 229 | 230 |
| 230 void VirtualFrame::PrepareForCall(int frame_arg_count) { | 231 void VirtualFrame::PrepareForCall(int frame_arg_count) { |
| 231 ASSERT(height() >= frame_arg_count); | 232 ASSERT(height() >= frame_arg_count); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 FrameElement element = elements_[i]; | 291 FrameElement element = elements_[i]; |
| 291 if (element.is_constant() || | 292 if (element.is_constant() || |
| 292 (element.is_register() && | 293 (element.is_register() && |
| 293 frame_registers_.count(element.reg().code()) > 1)) { | 294 frame_registers_.count(element.reg().code()) > 1)) { |
| 294 // A simple strategy is to locate these elements in memory if they are | 295 // A simple strategy is to locate these elements in memory if they are |
| 295 // synced (avoiding a spill right now) and otherwise to prefer a | 296 // synced (avoiding a spill right now) and otherwise to prefer a |
| 296 // register for them. | 297 // register for them. |
| 297 if (element.is_synced()) { | 298 if (element.is_synced()) { |
| 298 new_elements[i] = memory_element; | 299 new_elements[i] = memory_element; |
| 299 } else { | 300 } else { |
| 300 // This code path is currently not triggered. UNIMPLEMENTED is | |
| 301 // temporarily used to trap when it becomes active so we can test | |
| 302 // it. | |
| 303 UNIMPLEMENTED(); | |
| 304 Register reg = cgen_->allocator()->AllocateWithoutSpilling(); | 301 Register reg = cgen_->allocator()->AllocateWithoutSpilling(); |
| 305 if (reg.is(no_reg)) { | 302 if (reg.is(no_reg)) { |
| 306 new_elements[i] = memory_element; | 303 new_elements[i] = memory_element; |
| 307 } else { | 304 } else { |
| 308 FrameElement register_element(reg, FrameElement::NOT_SYNCED); | 305 FrameElement register_element(reg, FrameElement::NOT_SYNCED); |
| 309 new_elements[i] = register_element; | 306 new_elements[i] = register_element; |
| 310 } | 307 } |
| 311 } | 308 } |
| 312 | 309 |
| 313 // We have not moved register references, but record that we will so | 310 // We have not moved register references, but record that we will so |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 ASSERT(!elements_[j].is_memory()); | 401 ASSERT(!elements_[j].is_memory()); |
| 405 } | 402 } |
| 406 #endif | 403 #endif |
| 407 stack_pointer_ = i + 1; | 404 stack_pointer_ = i + 1; |
| 408 __ add(Operand(esp), | 405 __ add(Operand(esp), |
| 409 Immediate((stack_pointer_ - i) * kPointerSize)); | 406 Immediate((stack_pointer_ - i) * kPointerSize)); |
| 410 } | 407 } |
| 411 stack_pointer_--; | 408 stack_pointer_--; |
| 412 __ pop(target.reg()); | 409 __ pop(target.reg()); |
| 413 } | 410 } |
| 414 Use(target.reg()); | 411 } else { |
| 415 } else if (source.is_constant()) { | 412 // Source is constant. |
| 416 // Not yet implemented. When done, code in common with the | 413 __ Set(target.reg(), Immediate(source.handle())); |
| 417 // memory-to-register just above case can be factored out. | |
| 418 UNIMPLEMENTED(); | |
| 419 } | 414 } |
| 415 Use(target.reg()); |
| 420 elements_[i] = target; | 416 elements_[i] = target; |
| 421 } | 417 } |
| 422 } | 418 } |
| 423 | 419 |
| 420 // At this point, the frames should be identical. |
| 424 ASSERT(stack_pointer_ == expected->stack_pointer_); | 421 ASSERT(stack_pointer_ == expected->stack_pointer_); |
| 422 #ifdef DEBUG |
| 423 for (int i = 0; i < elements_.length(); i++) { |
| 424 FrameElement expect = expected->elements_[i]; |
| 425 if (expect.is_memory()) { |
| 426 ASSERT(elements_[i].is_memory()); |
| 427 ASSERT(elements_[i].is_synced() && expect.is_synced()); |
| 428 } else if (expect.is_register()) { |
| 429 ASSERT(elements_[i].is_register()); |
| 430 ASSERT(elements_[i].reg().is(expect.reg())); |
| 431 ASSERT(elements_[i].is_synced() == expect.is_synced()); |
| 432 } else { |
| 433 ASSERT(expect.is_constant()); |
| 434 ASSERT(elements_[i].is_constant()); |
| 435 ASSERT(elements_[i].handle().location() == |
| 436 expect.handle().location()); |
| 437 ASSERT(elements_[i].is_synced() == expect.is_synced()); |
| 438 } |
| 439 } |
| 440 #endif |
| 425 } | 441 } |
| 426 | 442 |
| 427 | 443 |
| 428 void VirtualFrame::Enter() { | 444 void VirtualFrame::Enter() { |
| 429 // Registers live on entry: esp, ebp, esi, edi. | 445 // Registers live on entry: esp, ebp, esi, edi. |
| 430 Comment cmnt(masm_, "[ Enter JS frame"); | 446 Comment cmnt(masm_, "[ Enter JS frame"); |
| 431 EmitPush(ebp); | 447 EmitPush(ebp); |
| 432 | 448 |
| 433 frame_pointer_ = stack_pointer_; | 449 frame_pointer_ = stack_pointer_; |
| 434 __ mov(ebp, Operand(esp)); | 450 __ mov(ebp, Operand(esp)); |
| 435 | 451 |
| 436 // Store the context and the function in the frame. | 452 // Store the context in the frame. The context is kept in esi, so the |
| 437 Push(esi); | 453 // register reference is not owned by the frame (ie, the frame is not free |
| 438 // The frame owns the register reference now. | 454 // to spill it). This is implemented by making the in-frame value be |
| 439 cgen_->allocator()->Unuse(esi); | 455 // memory. |
| 456 EmitPush(esi); |
| 440 | 457 |
| 458 // Store the function in the frame. The frame owns the register reference |
| 459 // now (ie, it can keep it in edi or spill it later). |
| 441 Push(edi); | 460 Push(edi); |
| 442 cgen_->allocator()->Unuse(edi); | 461 cgen_->allocator()->Unuse(edi); |
| 443 } | 462 } |
| 444 | 463 |
| 445 | 464 |
| 446 void VirtualFrame::Exit() { | 465 void VirtualFrame::Exit() { |
| 447 Comment cmnt(masm_, "[ Exit JS frame"); | 466 Comment cmnt(masm_, "[ Exit JS frame"); |
| 448 // Record the location of the JS exit code for patching when setting | 467 // Record the location of the JS exit code for patching when setting |
| 449 // break point. | 468 // break point. |
| 450 __ RecordJSReturn(); | 469 __ RecordJSReturn(); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 return false; | 674 return false; |
| 656 } | 675 } |
| 657 } | 676 } |
| 658 return true; | 677 return true; |
| 659 } | 678 } |
| 660 #endif | 679 #endif |
| 661 | 680 |
| 662 #undef __ | 681 #undef __ |
| 663 | 682 |
| 664 } } // namespace v8::internal | 683 } } // namespace v8::internal |
| OLD | NEW |