Chromium Code Reviews| 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 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 return true; | 302 return true; |
| 303 } | 303 } |
| 304 } | 304 } |
| 305 | 305 |
| 306 return false; | 306 return false; |
| 307 } | 307 } |
| 308 | 308 |
| 309 | 309 |
| 310 void VirtualFrame::MakeMergable() { | 310 void VirtualFrame::MakeMergable() { |
| 311 Comment cmnt(masm_, "[ Make frame mergable"); | 311 Comment cmnt(masm_, "[ Make frame mergable"); |
| 312 // We can call MakeMergable on a frame that is not the code generator's | |
| 313 // current frame, which will leave the global register counts out of sync | |
| 314 // with the frame. We simply save the current frame and restore it at the | |
| 315 // end of this function. We should find a better way to deal with this. | |
| 316 VirtualFrame* original_frame = cgen_->frame(); | |
| 317 RegisterFile non_frame_registers; | |
| 318 non_frame_registers.Use(esi); | |
| 319 non_frame_registers.Use(ebp); | |
| 320 non_frame_registers.Use(esp); | |
| 321 cgen_->SetFrame(this, &non_frame_registers); | |
|
William Hesse
2009/01/15 12:21:54
Can you put an assert in, that the frame is its cg
Kevin Millikin (Chromium)
2009/01/15 13:08:18
Done.
| |
| 322 ASSERT(cgen_->HasValidEntryRegisters()); | 312 ASSERT(cgen_->HasValidEntryRegisters()); |
| 323 | 313 |
| 324 // Remove constants from the frame and ensure that no registers are | 314 // Remove constants from the frame and ensure that no registers are |
| 325 // multiply referenced within the frame. Allocate elements to their new | 315 // multiply referenced within the frame. Allocate elements to their new |
| 326 // locations from the top down so that the topmost elements have a chance | 316 // locations from the top down so that the topmost elements have a chance |
| 327 // to be in registers, then fill them into memory from the bottom up. | 317 // to be in registers, then fill them into memory from the bottom up. |
| 328 // (NB: Currently when spilling registers that are multiply referenced, it | 318 // (NB: Currently when spilling registers that are multiply referenced, it |
| 329 // is the lowermost occurrence that gets to stay in the register.) | 319 // is the lowermost occurrence that gets to stay in the register.) |
| 330 | 320 |
| 331 // The elements of new_elements are initially invalid. | 321 // The elements of new_elements are initially invalid. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 // but we have already done that when computing new target elements, | 375 // but we have already done that when computing new target elements, |
| 386 // so we use a raw spill. | 376 // so we use a raw spill. |
| 387 RawSpillElementAt(i); | 377 RawSpillElementAt(i); |
| 388 } | 378 } |
| 389 } | 379 } |
| 390 // Invalid elements do not need to be moved. | 380 // Invalid elements do not need to be moved. |
| 391 } | 381 } |
| 392 | 382 |
| 393 delete[] new_elements; | 383 delete[] new_elements; |
| 394 ASSERT(cgen_->HasValidEntryRegisters()); | 384 ASSERT(cgen_->HasValidEntryRegisters()); |
| 395 cgen_->SetFrame(original_frame, &non_frame_registers); | |
| 396 } | 385 } |
| 397 | 386 |
| 398 | 387 |
| 399 void VirtualFrame::MergeTo(VirtualFrame* expected) { | 388 void VirtualFrame::MergeTo(VirtualFrame* expected) { |
| 400 Comment cmnt(masm_, "[ Merge frame"); | 389 Comment cmnt(masm_, "[ Merge frame"); |
| 401 // We should always be merging the code generator's current frame to an | 390 // We should always be merging the code generator's current frame to an |
| 402 // expected frame. | 391 // expected frame. |
| 403 ASSERT(cgen_->frame() == this); | 392 ASSERT(cgen_->frame() == this); |
| 404 | 393 |
| 405 ASSERT(cgen_ == expected->cgen_); | 394 ASSERT(cgen_ == expected->cgen_); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 419 MergeMoveMemoryToRegisters(expected); | 408 MergeMoveMemoryToRegisters(expected); |
| 420 | 409 |
| 421 int height_difference = stack_pointer_ - expected->stack_pointer_; | 410 int height_difference = stack_pointer_ - expected->stack_pointer_; |
| 422 if (stack_pointer_ > expected->stack_pointer_) { | 411 if (stack_pointer_ > expected->stack_pointer_) { |
| 423 #ifdef DEBUG | 412 #ifdef DEBUG |
| 424 for (int i = stack_pointer_; i > expected->stack_pointer_; i--) { | 413 for (int i = stack_pointer_; i > expected->stack_pointer_; i--) { |
| 425 ASSERT(!elements_[i].is_memory()); | 414 ASSERT(!elements_[i].is_memory()); |
| 426 ASSERT(!elements_[i].is_synced()); | 415 ASSERT(!elements_[i].is_synced()); |
| 427 } | 416 } |
| 428 #endif | 417 #endif |
| 418 ASSERT(!cgen_->has_cc()); | |
| 429 __ add(Operand(esp), Immediate(height_difference * kPointerSize)); | 419 __ add(Operand(esp), Immediate(height_difference * kPointerSize)); |
| 430 stack_pointer_ = expected->stack_pointer_; | 420 stack_pointer_ = expected->stack_pointer_; |
| 431 } else if (stack_pointer_ < expected->stack_pointer_) { | 421 } else if (stack_pointer_ < expected->stack_pointer_) { |
| 432 // Put valid data on the stack, that will only be accessed by GC. | 422 // Put valid data on the stack, that will only be accessed by GC. |
| 433 while (stack_pointer_ < expected->stack_pointer_) { | 423 while (stack_pointer_ < expected->stack_pointer_) { |
| 434 __ push(Immediate(Smi::FromInt(0))); | 424 __ push(Immediate(Smi::FromInt(0))); |
| 435 stack_pointer_++; | 425 stack_pointer_++; |
| 436 } | 426 } |
| 437 } | 427 } |
| 438 | 428 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 // pointer downward. | 546 // pointer downward. |
| 557 if (stack_pointer_ > i) { | 547 if (stack_pointer_ > i) { |
| 558 // Sync elements between i and stack pointer, and bring | 548 // Sync elements between i and stack pointer, and bring |
| 559 // stack pointer down to i. | 549 // stack pointer down to i. |
| 560 #ifdef DEBUG | 550 #ifdef DEBUG |
| 561 // In debug builds check to ensure this is safe. | 551 // In debug builds check to ensure this is safe. |
| 562 for (int j = stack_pointer_; j > i; j--) { | 552 for (int j = stack_pointer_; j > i; j--) { |
| 563 ASSERT(!elements_[j].is_memory()); | 553 ASSERT(!elements_[j].is_memory()); |
| 564 } | 554 } |
| 565 #endif | 555 #endif |
| 566 __ add(Operand(esp), | 556 int difference = stack_pointer_ - i; |
| 567 Immediate((stack_pointer_ - i) * kPointerSize)); | 557 ASSERT(!cgen_->has_cc()); |
| 558 __ add(Operand(esp), Immediate(difference * kPointerSize)); | |
| 568 stack_pointer_ = i; | 559 stack_pointer_ = i; |
| 569 } | 560 } |
| 570 stack_pointer_--; | 561 stack_pointer_--; |
| 571 __ pop(target.reg()); | 562 __ pop(target.reg()); |
| 572 } | 563 } |
| 573 } else { | 564 } else { |
| 574 // Source is constant. | 565 // Source is constant. |
| 575 __ Set(target.reg(), Immediate(source.handle())); | 566 __ Set(target.reg(), Immediate(source.handle())); |
| 576 if (target.is_synced()) { | 567 if (target.is_synced()) { |
| 577 SyncElementAt(i); | 568 SyncElementAt(i); |
| 578 } | 569 } |
| 579 } | 570 } |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 931 | 922 |
| 932 | 923 |
| 933 void VirtualFrame::Drop(int count) { | 924 void VirtualFrame::Drop(int count) { |
| 934 ASSERT(height() >= count); | 925 ASSERT(height() >= count); |
| 935 int num_virtual_elements = (elements_.length() - 1) - stack_pointer_; | 926 int num_virtual_elements = (elements_.length() - 1) - stack_pointer_; |
| 936 | 927 |
| 937 // Emit code to lower the stack pointer if necessary. | 928 // Emit code to lower the stack pointer if necessary. |
| 938 if (num_virtual_elements < count) { | 929 if (num_virtual_elements < count) { |
| 939 int num_dropped = count - num_virtual_elements; | 930 int num_dropped = count - num_virtual_elements; |
| 940 stack_pointer_ -= num_dropped; | 931 stack_pointer_ -= num_dropped; |
| 932 ASSERT(!cgen_->has_cc()); | |
| 941 __ add(Operand(esp), Immediate(num_dropped * kPointerSize)); | 933 __ add(Operand(esp), Immediate(num_dropped * kPointerSize)); |
| 942 } | 934 } |
| 943 | 935 |
| 944 // Discard elements from the virtual frame and free any registers. | 936 // Discard elements from the virtual frame and free any registers. |
| 945 for (int i = 0; i < count; i++) { | 937 for (int i = 0; i < count; i++) { |
| 946 FrameElement dropped = elements_.RemoveLast(); | 938 FrameElement dropped = elements_.RemoveLast(); |
| 947 if (dropped.is_register()) { | 939 if (dropped.is_register()) { |
| 948 Unuse(dropped.reg()); | 940 Unuse(dropped.reg()); |
| 949 } | 941 } |
| 950 } | 942 } |
| 951 } | 943 } |
| 952 | 944 |
| 953 | 945 |
| 954 Result VirtualFrame::Pop() { | 946 Result VirtualFrame::Pop() { |
| 955 FrameElement popped = elements_.RemoveLast(); | 947 FrameElement popped = elements_.RemoveLast(); |
| 956 bool pop_needed = (stack_pointer_ == elements_.length()); | 948 bool pop_needed = (stack_pointer_ == elements_.length()); |
| 957 | 949 |
| 958 if (popped.is_constant()) { | 950 if (popped.is_constant()) { |
| 959 if (pop_needed) { | 951 if (pop_needed) { |
| 960 stack_pointer_--; | 952 stack_pointer_--; |
| 953 ASSERT(!cgen_->has_cc()); | |
| 961 __ add(Operand(esp), Immediate(kPointerSize)); | 954 __ add(Operand(esp), Immediate(kPointerSize)); |
| 962 } | 955 } |
| 963 return Result(popped.handle(), cgen_); | 956 return Result(popped.handle(), cgen_); |
| 964 } else if (popped.is_register()) { | 957 } else if (popped.is_register()) { |
| 965 Unuse(popped.reg()); | 958 Unuse(popped.reg()); |
| 966 if (pop_needed) { | 959 if (pop_needed) { |
| 967 stack_pointer_--; | 960 stack_pointer_--; |
| 961 ASSERT(!cgen_->has_cc()); | |
| 968 __ add(Operand(esp), Immediate(kPointerSize)); | 962 __ add(Operand(esp), Immediate(kPointerSize)); |
| 969 } | 963 } |
| 970 return Result(popped.reg(), cgen_); | 964 return Result(popped.reg(), cgen_); |
| 971 } else { | 965 } else { |
| 972 ASSERT(popped.is_memory()); | 966 ASSERT(popped.is_memory()); |
| 973 Result temp = cgen_->allocator()->Allocate(); | 967 Result temp = cgen_->allocator()->Allocate(); |
| 974 ASSERT(temp.is_valid()); | 968 ASSERT(temp.is_valid()); |
| 975 ASSERT(pop_needed); | 969 ASSERT(pop_needed); |
| 976 stack_pointer_--; | 970 stack_pointer_--; |
| 977 __ pop(temp.reg()); | 971 __ pop(temp.reg()); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1062 return false; | 1056 return false; |
| 1063 } | 1057 } |
| 1064 } | 1058 } |
| 1065 return true; | 1059 return true; |
| 1066 } | 1060 } |
| 1067 #endif | 1061 #endif |
| 1068 | 1062 |
| 1069 #undef __ | 1063 #undef __ |
| 1070 | 1064 |
| 1071 } } // namespace v8::internal | 1065 } } // namespace v8::internal |
| OLD | NEW |