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

Side by Side Diff: src/x64/virtual-frame-x64.cc

Issue 545007: Introduce number type information in the virtual frame. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: merged with latest rev. Created 10 years, 10 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
« no previous file with comments | « src/x64/virtual-frame-x64.h ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 27 matching lines...) Expand all
38 38
39 // ------------------------------------------------------------------------- 39 // -------------------------------------------------------------------------
40 // VirtualFrame implementation. 40 // VirtualFrame implementation.
41 41
42 // On entry to a function, the virtual frame already contains the receiver, 42 // On entry to a function, the virtual frame already contains the receiver,
43 // the parameters, and a return address. All frame elements are in memory. 43 // the parameters, and a return address. All frame elements are in memory.
44 VirtualFrame::VirtualFrame() 44 VirtualFrame::VirtualFrame()
45 : elements_(parameter_count() + local_count() + kPreallocatedElements), 45 : elements_(parameter_count() + local_count() + kPreallocatedElements),
46 stack_pointer_(parameter_count() + 1) { // 0-based index of TOS. 46 stack_pointer_(parameter_count() + 1) { // 0-based index of TOS.
47 for (int i = 0; i <= stack_pointer_; i++) { 47 for (int i = 0; i <= stack_pointer_; i++) {
48 elements_.Add(FrameElement::MemoryElement()); 48 elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
49 } 49 }
50 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { 50 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
51 register_locations_[i] = kIllegalIndex; 51 register_locations_[i] = kIllegalIndex;
52 } 52 }
53 } 53 }
54 54
55 55
56 void VirtualFrame::Enter() { 56 void VirtualFrame::Enter() {
57 // Registers live on entry to a JS frame: 57 // Registers live on entry to a JS frame:
58 // rsp: stack pointer, points to return address from this function. 58 // rsp: stack pointer, points to return address from this function.
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 186
187 187
188 void VirtualFrame::EmitPop(const Operand& operand) { 188 void VirtualFrame::EmitPop(const Operand& operand) {
189 ASSERT(stack_pointer_ == element_count() - 1); 189 ASSERT(stack_pointer_ == element_count() - 1);
190 stack_pointer_--; 190 stack_pointer_--;
191 elements_.RemoveLast(); 191 elements_.RemoveLast();
192 __ pop(operand); 192 __ pop(operand);
193 } 193 }
194 194
195 195
196 void VirtualFrame::EmitPush(Register reg) { 196 void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) {
197 ASSERT(stack_pointer_ == element_count() - 1); 197 ASSERT(stack_pointer_ == element_count() - 1);
198 elements_.Add(FrameElement::MemoryElement()); 198 elements_.Add(FrameElement::MemoryElement(info));
199 stack_pointer_++; 199 stack_pointer_++;
200 __ push(reg); 200 __ push(reg);
201 } 201 }
202 202
203 203
204 void VirtualFrame::EmitPush(const Operand& operand) { 204 void VirtualFrame::EmitPush(const Operand& operand, NumberInfo::Type info) {
205 ASSERT(stack_pointer_ == element_count() - 1); 205 ASSERT(stack_pointer_ == element_count() - 1);
206 elements_.Add(FrameElement::MemoryElement()); 206 elements_.Add(FrameElement::MemoryElement(info));
207 stack_pointer_++; 207 stack_pointer_++;
208 __ push(operand); 208 __ push(operand);
209 } 209 }
210 210
211 211
212 void VirtualFrame::EmitPush(Immediate immediate) { 212 void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) {
213 ASSERT(stack_pointer_ == element_count() - 1); 213 ASSERT(stack_pointer_ == element_count() - 1);
214 elements_.Add(FrameElement::MemoryElement()); 214 elements_.Add(FrameElement::MemoryElement(info));
215 stack_pointer_++; 215 stack_pointer_++;
216 __ push(immediate); 216 __ push(immediate);
217 } 217 }
218 218
219 219
220 void VirtualFrame::EmitPush(Smi* smi_value) { 220 void VirtualFrame::EmitPush(Smi* smi_value) {
221 ASSERT(stack_pointer_ == element_count() - 1); 221 ASSERT(stack_pointer_ == element_count() - 1);
222 elements_.Add(FrameElement::MemoryElement()); 222 elements_.Add(FrameElement::MemoryElement(NumberInfo::kSmi));
223 stack_pointer_++; 223 stack_pointer_++;
224 __ Push(smi_value); 224 __ Push(smi_value);
225 } 225 }
226 226
227 227
228 void VirtualFrame::EmitPush(Handle<Object> value) { 228 void VirtualFrame::EmitPush(Handle<Object> value) {
229 ASSERT(stack_pointer_ == element_count() - 1); 229 ASSERT(stack_pointer_ == element_count() - 1);
230 elements_.Add(FrameElement::MemoryElement()); 230 NumberInfo::Type info = NumberInfo::kUnknown;
231 if (value->IsSmi()) {
232 info = NumberInfo::kSmi;
233 } else if (value->IsHeapNumber()) {
234 info = NumberInfo::kHeapNumber;
235 }
236 elements_.Add(FrameElement::MemoryElement(info));
231 stack_pointer_++; 237 stack_pointer_++;
232 __ Push(value); 238 __ Push(value);
233 } 239 }
234 240
235 241
236 void VirtualFrame::EmitPush(Heap::RootListIndex index) { 242 void VirtualFrame::EmitPush(Heap::RootListIndex index, NumberInfo::Type info) {
237 ASSERT(stack_pointer_ == element_count() - 1); 243 ASSERT(stack_pointer_ == element_count() - 1);
238 elements_.Add(FrameElement::MemoryElement()); 244 elements_.Add(FrameElement::MemoryElement(info));
239 stack_pointer_++; 245 stack_pointer_++;
240 __ PushRoot(index); 246 __ PushRoot(index);
241 } 247 }
242 248
243 249
244 void VirtualFrame::Drop(int count) { 250 void VirtualFrame::Drop(int count) {
245 ASSERT(count >= 0); 251 ASSERT(count >= 0);
246 ASSERT(height() >= count); 252 ASSERT(height() >= count);
247 int num_virtual_elements = (element_count() - 1) - stack_pointer_; 253 int num_virtual_elements = (element_count() - 1) - stack_pointer_;
248 254
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 } else { 304 } else {
299 // The original was in a register. 305 // The original was in a register.
300 backing_reg = original.reg(); 306 backing_reg = original.reg();
301 set_register_location(backing_reg, new_backing_index); 307 set_register_location(backing_reg, new_backing_index);
302 } 308 }
303 // Invalidate the element at index. 309 // Invalidate the element at index.
304 elements_[index] = FrameElement::InvalidElement(); 310 elements_[index] = FrameElement::InvalidElement();
305 // Set the new backing element. 311 // Set the new backing element.
306 if (elements_[new_backing_index].is_synced()) { 312 if (elements_[new_backing_index].is_synced()) {
307 elements_[new_backing_index] = 313 elements_[new_backing_index] =
308 FrameElement::RegisterElement(backing_reg, FrameElement::SYNCED); 314 FrameElement::RegisterElement(backing_reg,
315 FrameElement::SYNCED,
316 original.number_info());
309 } else { 317 } else {
310 elements_[new_backing_index] = 318 elements_[new_backing_index] =
311 FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED); 319 FrameElement::RegisterElement(backing_reg,
320 FrameElement::NOT_SYNCED,
321 original.number_info());
312 } 322 }
313 // Update the other copies. 323 // Update the other copies.
314 for (int i = new_backing_index + 1; i < element_count(); i++) { 324 for (int i = new_backing_index + 1; i < element_count(); i++) {
315 if (elements_[i].is_copy() && elements_[i].index() == index) { 325 if (elements_[i].is_copy() && elements_[i].index() == index) {
316 elements_[i].set_index(new_backing_index); 326 elements_[i].set_index(new_backing_index);
317 elements_[new_backing_index].set_copied(); 327 elements_[new_backing_index].set_copied();
318 } 328 }
319 } 329 }
320 return new_backing_index; 330 return new_backing_index;
321 } 331 }
(...skipping 10 matching lines...) Expand all
332 } 342 }
333 343
334 switch (original.type()) { 344 switch (original.type()) {
335 case FrameElement::MEMORY: { 345 case FrameElement::MEMORY: {
336 // Emit code to load the original element's data into a register. 346 // Emit code to load the original element's data into a register.
337 // Push that register as a FrameElement on top of the frame. 347 // Push that register as a FrameElement on top of the frame.
338 Result fresh = cgen()->allocator()->Allocate(); 348 Result fresh = cgen()->allocator()->Allocate();
339 ASSERT(fresh.is_valid()); 349 ASSERT(fresh.is_valid());
340 FrameElement new_element = 350 FrameElement new_element =
341 FrameElement::RegisterElement(fresh.reg(), 351 FrameElement::RegisterElement(fresh.reg(),
342 FrameElement::NOT_SYNCED); 352 FrameElement::NOT_SYNCED,
353 original.number_info());
343 Use(fresh.reg(), element_count()); 354 Use(fresh.reg(), element_count());
344 elements_.Add(new_element); 355 elements_.Add(new_element);
345 __ movq(fresh.reg(), Operand(rbp, fp_relative(index))); 356 __ movq(fresh.reg(), Operand(rbp, fp_relative(index)));
346 break; 357 break;
347 } 358 }
348 case FrameElement::REGISTER: 359 case FrameElement::REGISTER:
349 Use(original.reg(), element_count()); 360 Use(original.reg(), element_count());
350 // Fall through. 361 // Fall through.
351 case FrameElement::CONSTANT: 362 case FrameElement::CONSTANT:
352 case FrameElement::COPY: 363 case FrameElement::COPY:
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 ASSERT(top.is_constant()); 484 ASSERT(top.is_constant());
474 elements_[index].clear_sync(); 485 elements_[index].clear_sync();
475 } 486 }
476 } 487 }
477 488
478 489
479 void VirtualFrame::MakeMergable() { 490 void VirtualFrame::MakeMergable() {
480 for (int i = 0; i < element_count(); i++) { 491 for (int i = 0; i < element_count(); i++) {
481 FrameElement element = elements_[i]; 492 FrameElement element = elements_[i];
482 493
494 // In all cases we have to reset the number type information
495 // to unknown for a mergable frame because of incoming back edges.
483 if (element.is_constant() || element.is_copy()) { 496 if (element.is_constant() || element.is_copy()) {
484 if (element.is_synced()) { 497 if (element.is_synced()) {
485 // Just spill. 498 // Just spill.
486 elements_[i] = FrameElement::MemoryElement(); 499 elements_[i] = FrameElement::MemoryElement(NumberInfo::kUnknown);
487 } else { 500 } else {
488 // Allocate to a register. 501 // Allocate to a register.
489 FrameElement backing_element; // Invalid if not a copy. 502 FrameElement backing_element; // Invalid if not a copy.
490 if (element.is_copy()) { 503 if (element.is_copy()) {
491 backing_element = elements_[element.index()]; 504 backing_element = elements_[element.index()];
492 } 505 }
493 Result fresh = cgen()->allocator()->Allocate(); 506 Result fresh = cgen()->allocator()->Allocate();
494 ASSERT(fresh.is_valid()); // A register was spilled if all were in use. 507 ASSERT(fresh.is_valid()); // A register was spilled if all were in use.
495 elements_[i] = 508 elements_[i] =
496 FrameElement::RegisterElement(fresh.reg(), 509 FrameElement::RegisterElement(fresh.reg(),
497 FrameElement::NOT_SYNCED); 510 FrameElement::NOT_SYNCED,
511 NumberInfo::kUnknown);
498 Use(fresh.reg(), i); 512 Use(fresh.reg(), i);
499 513
500 // Emit a move. 514 // Emit a move.
501 if (element.is_constant()) { 515 if (element.is_constant()) {
502 __ Move(fresh.reg(), element.handle()); 516 __ Move(fresh.reg(), element.handle());
503 } else { 517 } else {
504 ASSERT(element.is_copy()); 518 ASSERT(element.is_copy());
505 // Copies are only backed by register or memory locations. 519 // Copies are only backed by register or memory locations.
506 if (backing_element.is_register()) { 520 if (backing_element.is_register()) {
507 // The backing store may have been spilled by allocating, 521 // The backing store may have been spilled by allocating,
508 // but that's OK. If it was, the value is right where we 522 // but that's OK. If it was, the value is right where we
509 // want it. 523 // want it.
510 if (!fresh.reg().is(backing_element.reg())) { 524 if (!fresh.reg().is(backing_element.reg())) {
511 __ movq(fresh.reg(), backing_element.reg()); 525 __ movq(fresh.reg(), backing_element.reg());
512 } 526 }
513 } else { 527 } else {
514 ASSERT(backing_element.is_memory()); 528 ASSERT(backing_element.is_memory());
515 __ movq(fresh.reg(), Operand(rbp, fp_relative(element.index()))); 529 __ movq(fresh.reg(), Operand(rbp, fp_relative(element.index())));
516 } 530 }
517 } 531 }
518 } 532 }
519 // No need to set the copied flag --- there are no copies. 533 // No need to set the copied flag --- there are no copies.
520 } else { 534 } else {
521 // Clear the copy flag of non-constant, non-copy elements. 535 // Clear the copy flag of non-constant, non-copy elements.
522 // They cannot be copied because copies are not allowed. 536 // They cannot be copied because copies are not allowed.
523 // The copy flag is not relied on before the end of this loop, 537 // The copy flag is not relied on before the end of this loop,
524 // including when registers are spilled. 538 // including when registers are spilled.
525 elements_[i].clear_copied(); 539 elements_[i].clear_copied();
540 elements_[i].set_number_info(NumberInfo::kUnknown);
526 } 541 }
527 } 542 }
528 } 543 }
529 544
530 545
531 void VirtualFrame::MergeTo(VirtualFrame* expected) { 546 void VirtualFrame::MergeTo(VirtualFrame* expected) {
532 Comment cmnt(masm(), "[ Merge frame"); 547 Comment cmnt(masm(), "[ Merge frame");
533 // We should always be merging the code generator's current frame to an 548 // We should always be merging the code generator's current frame to an
534 // expected frame. 549 // expected frame.
535 ASSERT(cgen()->frame() == this); 550 ASSERT(cgen()->frame() == this);
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 } 736 }
722 } 737 }
723 } 738 }
724 739
725 740
726 Result VirtualFrame::Pop() { 741 Result VirtualFrame::Pop() {
727 FrameElement element = elements_.RemoveLast(); 742 FrameElement element = elements_.RemoveLast();
728 int index = element_count(); 743 int index = element_count();
729 ASSERT(element.is_valid()); 744 ASSERT(element.is_valid());
730 745
746 // Get number type information of the result.
747 NumberInfo::Type info;
748 if (!element.is_copy()) {
749 info = element.number_info();
750 } else {
751 info = elements_[element.index()].number_info();
752 }
753
731 bool pop_needed = (stack_pointer_ == index); 754 bool pop_needed = (stack_pointer_ == index);
732 if (pop_needed) { 755 if (pop_needed) {
733 stack_pointer_--; 756 stack_pointer_--;
734 if (element.is_memory()) { 757 if (element.is_memory()) {
735 Result temp = cgen()->allocator()->Allocate(); 758 Result temp = cgen()->allocator()->Allocate();
736 ASSERT(temp.is_valid()); 759 ASSERT(temp.is_valid());
737 __ pop(temp.reg()); 760 __ pop(temp.reg());
761 temp.set_number_info(info);
738 return temp; 762 return temp;
739 } 763 }
740 764
741 __ addq(rsp, Immediate(kPointerSize)); 765 __ addq(rsp, Immediate(kPointerSize));
742 } 766 }
743 ASSERT(!element.is_memory()); 767 ASSERT(!element.is_memory());
744 768
745 // The top element is a register, constant, or a copy. Unuse 769 // The top element is a register, constant, or a copy. Unuse
746 // registers and follow copies to their backing store. 770 // registers and follow copies to their backing store.
747 if (element.is_register()) { 771 if (element.is_register()) {
748 Unuse(element.reg()); 772 Unuse(element.reg());
749 } else if (element.is_copy()) { 773 } else if (element.is_copy()) {
750 ASSERT(element.index() < index); 774 ASSERT(element.index() < index);
751 index = element.index(); 775 index = element.index();
752 element = elements_[index]; 776 element = elements_[index];
753 } 777 }
754 ASSERT(!element.is_copy()); 778 ASSERT(!element.is_copy());
755 779
756 // The element is memory, a register, or a constant. 780 // The element is memory, a register, or a constant.
757 if (element.is_memory()) { 781 if (element.is_memory()) {
758 // Memory elements could only be the backing store of a copy. 782 // Memory elements could only be the backing store of a copy.
759 // Allocate the original to a register. 783 // Allocate the original to a register.
760 ASSERT(index <= stack_pointer_); 784 ASSERT(index <= stack_pointer_);
761 Result temp = cgen()->allocator()->Allocate(); 785 Result temp = cgen()->allocator()->Allocate();
762 ASSERT(temp.is_valid()); 786 ASSERT(temp.is_valid());
763 Use(temp.reg(), index); 787 Use(temp.reg(), index);
764 FrameElement new_element = 788 FrameElement new_element =
765 FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED); 789 FrameElement::RegisterElement(temp.reg(),
790 FrameElement::SYNCED,
791 element.number_info());
766 // Preserve the copy flag on the element. 792 // Preserve the copy flag on the element.
767 if (element.is_copied()) new_element.set_copied(); 793 if (element.is_copied()) new_element.set_copied();
768 elements_[index] = new_element; 794 elements_[index] = new_element;
769 __ movq(temp.reg(), Operand(rbp, fp_relative(index))); 795 __ movq(temp.reg(), Operand(rbp, fp_relative(index)));
770 return Result(temp.reg()); 796 return Result(temp.reg(), info);
771 } else if (element.is_register()) { 797 } else if (element.is_register()) {
772 return Result(element.reg()); 798 return Result(element.reg(), info);
773 } else { 799 } else {
774 ASSERT(element.is_constant()); 800 ASSERT(element.is_constant());
775 return Result(element.handle()); 801 return Result(element.handle());
776 } 802 }
777 } 803 }
778 804
779 805
780 Result VirtualFrame::RawCallStub(CodeStub* stub) { 806 Result VirtualFrame::RawCallStub(CodeStub* stub) {
781 ASSERT(cgen()->HasValidEntryRegisters()); 807 ASSERT(cgen()->HasValidEntryRegisters());
782 __ CallStub(stub); 808 __ CallStub(stub);
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 // Grow the expression stack by handler size less one (the return 1134 // Grow the expression stack by handler size less one (the return
1109 // address is already pushed by a call instruction). 1135 // address is already pushed by a call instruction).
1110 Adjust(kHandlerSize - 1); 1136 Adjust(kHandlerSize - 1);
1111 __ PushTryHandler(IN_JAVASCRIPT, type); 1137 __ PushTryHandler(IN_JAVASCRIPT, type);
1112 } 1138 }
1113 1139
1114 1140
1115 #undef __ 1141 #undef __
1116 1142
1117 } } // namespace v8::internal 1143 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/virtual-frame-x64.h ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698