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

Side by Side Diff: src/x64/full-codegen-x64.cc

Issue 7122003: Make x64 to use the RecordWrite stub. This is a step towards getting (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 6 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/code-stubs-x64.cc ('k') | src/x64/ic-x64.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 for (int i = 0; i < num_parameters; i++) { 187 for (int i = 0; i < num_parameters; i++) {
188 Slot* slot = scope()->parameter(i)->AsSlot(); 188 Slot* slot = scope()->parameter(i)->AsSlot();
189 if (slot != NULL && slot->type() == Slot::CONTEXT) { 189 if (slot != NULL && slot->type() == Slot::CONTEXT) {
190 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 190 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
191 (num_parameters - 1 - i) * kPointerSize; 191 (num_parameters - 1 - i) * kPointerSize;
192 // Load parameter from stack. 192 // Load parameter from stack.
193 __ movq(rax, Operand(rbp, parameter_offset)); 193 __ movq(rax, Operand(rbp, parameter_offset));
194 // Store it in the context. 194 // Store it in the context.
195 int context_offset = Context::SlotOffset(slot->index()); 195 int context_offset = Context::SlotOffset(slot->index());
196 __ movq(Operand(rsi, context_offset), rax); 196 __ movq(Operand(rsi, context_offset), rax);
197 // Update the write barrier. This clobbers all involved 197 // Update the write barrier. This clobbers rax and rbx.
198 // registers, so we have use a third register to avoid 198 __ RecordWriteContextSlot(
199 // clobbering rsi. 199 rsi, context_offset, rax, rbx, kDontSaveFPRegs);
200 __ movq(rcx, rsi);
201 __ RecordWrite(rcx, context_offset, rax, rbx, kDontSaveFPRegs);
202 } 200 }
203 } 201 }
204 } 202 }
205 203
206 // Possibly allocate an arguments object. 204 // Possibly allocate an arguments object.
207 Variable* arguments = scope()->arguments(); 205 Variable* arguments = scope()->arguments();
208 if (arguments != NULL) { 206 if (arguments != NULL) {
209 // Arguments object must be allocated after the context object, in 207 // Arguments object must be allocated after the context object, in
210 // case the "arguments" or ".arguments" variables are in the context. 208 // case the "arguments" or ".arguments" variables are in the context.
211 Comment cmnt(masm_, "[ Allocate arguments object"); 209 Comment cmnt(masm_, "[ Allocate arguments object");
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 617
620 618
621 void FullCodeGenerator::Move(Slot* dst, 619 void FullCodeGenerator::Move(Slot* dst,
622 Register src, 620 Register src,
623 Register scratch1, 621 Register scratch1,
624 Register scratch2) { 622 Register scratch2) {
625 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented. 623 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented.
626 ASSERT(!scratch1.is(src) && !scratch2.is(src)); 624 ASSERT(!scratch1.is(src) && !scratch2.is(src));
627 MemOperand location = EmitSlotSearch(dst, scratch1); 625 MemOperand location = EmitSlotSearch(dst, scratch1);
628 __ movq(location, src); 626 __ movq(location, src);
627
629 // Emit the write barrier code if the location is in the heap. 628 // Emit the write barrier code if the location is in the heap.
630 if (dst->type() == Slot::CONTEXT) { 629 if (dst->type() == Slot::CONTEXT) {
631 int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize; 630 int offset = Context::SlotOffset(dst->index());
632 __ RecordWrite(scratch1, offset, src, scratch2, kDontSaveFPRegs); 631 __ RecordWriteContextSlot(scratch1, offset, src, scratch2, kDontSaveFPRegs);
633 } 632 }
634 } 633 }
635 634
636 635
637 void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state, 636 void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state,
638 bool should_normalize, 637 bool should_normalize,
639 Label* if_true, 638 Label* if_true,
640 Label* if_false) { 639 Label* if_false) {
641 // Only prepare for bailouts before splits if we're in a test 640 // Only prepare for bailouts before splits if we're in a test
642 // context. Otherwise, we let the Visit function deal with the 641 // context. Otherwise, we let the Visit function deal with the
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 } 694 }
696 if (mode == Variable::CONST) { 695 if (mode == Variable::CONST) {
697 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 696 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
698 __ movq(ContextOperand(rsi, slot->index()), kScratchRegister); 697 __ movq(ContextOperand(rsi, slot->index()), kScratchRegister);
699 // No write barrier since the hole value is in old space. 698 // No write barrier since the hole value is in old space.
700 } else if (function != NULL) { 699 } else if (function != NULL) {
701 VisitForAccumulatorValue(function); 700 VisitForAccumulatorValue(function);
702 __ movq(ContextOperand(rsi, slot->index()), result_register()); 701 __ movq(ContextOperand(rsi, slot->index()), result_register());
703 int offset = Context::SlotOffset(slot->index()); 702 int offset = Context::SlotOffset(slot->index());
704 // We know that we have written a function, which is not a smi. 703 // We know that we have written a function, which is not a smi.
705 // TODO(gc): Make sure we omit Smi check here. 704 __ RecordWriteContextSlot(rsi,
706 __ RecordWrite(rsi, offset, result_register(), rcx, kDontSaveFPRegs); 705 offset,
706 result_register(),
707 rcx,
708 kDontSaveFPRegs,
709 EMIT_REMEMBERED_SET,
710 OMIT_SMI_CHECK);
707 } 711 }
708 break; 712 break;
709 713
710 case Slot::LOOKUP: { 714 case Slot::LOOKUP: {
711 __ push(rsi); 715 __ push(rsi);
712 __ Push(variable->name()); 716 __ Push(variable->name());
713 // Declaration nodes are always introduced in one of two modes. 717 // Declaration nodes are always introduced in one of two modes.
714 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 718 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
715 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY; 719 PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY;
716 __ Push(Smi::FromInt(attr)); 720 __ Push(Smi::FromInt(attr));
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 } 1508 }
1505 VisitForAccumulatorValue(subexpr); 1509 VisitForAccumulatorValue(subexpr);
1506 1510
1507 // Store the subexpression value in the array's elements. 1511 // Store the subexpression value in the array's elements.
1508 __ movq(rbx, Operand(rsp, 0)); // Copy of array literal. 1512 __ movq(rbx, Operand(rsp, 0)); // Copy of array literal.
1509 __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); 1513 __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset));
1510 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1514 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1511 __ movq(FieldOperand(rbx, offset), result_register()); 1515 __ movq(FieldOperand(rbx, offset), result_register());
1512 1516
1513 // Update the write barrier for the array store. 1517 // Update the write barrier for the array store.
1514 __ RecordWrite(rbx, offset, result_register(), rcx, kDontSaveFPRegs); 1518 __ RecordWriteField(rbx, offset, result_register(), rcx, kDontSaveFPRegs);
1515 1519
1516 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1520 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
1517 } 1521 }
1518 1522
1519 if (result_saved) { 1523 if (result_saved) {
1520 context()->PlugTOS(); 1524 context()->PlugTOS();
1521 } else { 1525 } else {
1522 context()->Plug(rax); 1526 context()->Plug(rax);
1523 } 1527 }
1524 } 1528 }
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
1845 __ movq(Operand(rbp, SlotOffset(slot)), rax); 1849 __ movq(Operand(rbp, SlotOffset(slot)), rax);
1846 break; 1850 break;
1847 case Slot::CONTEXT: { 1851 case Slot::CONTEXT: {
1848 __ movq(rcx, ContextOperand(rsi, Context::FCONTEXT_INDEX)); 1852 __ movq(rcx, ContextOperand(rsi, Context::FCONTEXT_INDEX));
1849 __ movq(rdx, ContextOperand(rcx, slot->index())); 1853 __ movq(rdx, ContextOperand(rcx, slot->index()));
1850 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 1854 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1851 __ j(not_equal, &skip); 1855 __ j(not_equal, &skip);
1852 __ movq(ContextOperand(rcx, slot->index()), rax); 1856 __ movq(ContextOperand(rcx, slot->index()), rax);
1853 int offset = Context::SlotOffset(slot->index()); 1857 int offset = Context::SlotOffset(slot->index());
1854 __ movq(rdx, rax); // Preserve the stored value in eax. 1858 __ movq(rdx, rax); // Preserve the stored value in eax.
1855 __ RecordWrite(rcx, offset, rdx, rbx, kDontSaveFPRegs); 1859 __ RecordWriteContextSlot(rcx, offset, rdx, rbx, kDontSaveFPRegs);
1856 break; 1860 break;
1857 } 1861 }
1858 case Slot::LOOKUP: 1862 case Slot::LOOKUP:
1859 __ push(rax); 1863 __ push(rax);
1860 __ push(rsi); 1864 __ push(rsi);
1861 __ Push(var->name()); 1865 __ Push(var->name());
1862 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 1866 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1863 break; 1867 break;
1864 } 1868 }
1865 __ bind(&skip); 1869 __ bind(&skip);
1866 1870
1867 } else if (var->mode() != Variable::CONST) { 1871 } else if (var->mode() != Variable::CONST) {
1868 // Perform the assignment for non-const variables. Const assignments 1872 // Perform the assignment for non-const variables. Const assignments
1869 // are simply skipped. 1873 // are simply skipped.
1870 Slot* slot = var->AsSlot(); 1874 Slot* slot = var->AsSlot();
1871 switch (slot->type()) { 1875 switch (slot->type()) {
1872 case Slot::PARAMETER: 1876 case Slot::PARAMETER:
1873 case Slot::LOCAL: 1877 case Slot::LOCAL:
1874 // Perform the assignment. 1878 // Perform the assignment.
1875 __ movq(Operand(rbp, SlotOffset(slot)), rax); 1879 __ movq(Operand(rbp, SlotOffset(slot)), rax);
1876 break; 1880 break;
1877 1881
1878 case Slot::CONTEXT: { 1882 case Slot::CONTEXT: {
1879 MemOperand target = EmitSlotSearch(slot, rcx); 1883 MemOperand target = EmitSlotSearch(slot, rcx);
1880 // Perform the assignment and issue the write barrier. 1884 // Perform the assignment and issue the write barrier.
1881 __ movq(target, rax); 1885 __ movq(target, rax);
1882 1886
1883 // The value of the assignment is in rax. RecordWrite clobbers its 1887 // The value of the assignment is in rax. RecordWrite clobbers its
1884 // register arguments. 1888 // last two register arguments.
1885 __ movq(rdx, rax); 1889 __ movq(rdx, rax);
1886 int offset = Context::SlotOffset(slot->index()); 1890 int offset = Context::SlotOffset(slot->index());
1887 __ RecordWrite(rcx, offset, rdx, rbx, kDontSaveFPRegs); 1891 __ RecordWriteContextSlot(rcx, offset, rdx, rbx, kDontSaveFPRegs);
1888 break; 1892 break;
1889 } 1893 }
1890 1894
1891 case Slot::LOOKUP: 1895 case Slot::LOOKUP:
1892 // Call the runtime for the assignment. 1896 // Call the runtime for the assignment.
1893 __ push(rax); // Value. 1897 __ push(rax); // Value.
1894 __ push(rsi); // Context. 1898 __ push(rsi); // Context.
1895 __ Push(var->name()); 1899 __ Push(var->name());
1896 __ Push(Smi::FromInt(strict_mode_flag())); 1900 __ Push(Smi::FromInt(strict_mode_flag()));
1897 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1901 __ CallRuntime(Runtime::kStoreContextSlot, 4);
(...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after
2851 2855
2852 // If the object is not a value type, return the value. 2856 // If the object is not a value type, return the value.
2853 __ CmpObjectType(rbx, JS_VALUE_TYPE, rcx); 2857 __ CmpObjectType(rbx, JS_VALUE_TYPE, rcx);
2854 __ j(not_equal, &done); 2858 __ j(not_equal, &done);
2855 2859
2856 // Store the value. 2860 // Store the value.
2857 __ movq(FieldOperand(rbx, JSValue::kValueOffset), rax); 2861 __ movq(FieldOperand(rbx, JSValue::kValueOffset), rax);
2858 // Update the write barrier. Save the value as it will be 2862 // Update the write barrier. Save the value as it will be
2859 // overwritten by the write barrier code and is needed afterward. 2863 // overwritten by the write barrier code and is needed afterward.
2860 __ movq(rdx, rax); 2864 __ movq(rdx, rax);
2861 __ RecordWrite(rbx, JSValue::kValueOffset, rdx, rcx, kDontSaveFPRegs); 2865 __ RecordWriteField(rbx, JSValue::kValueOffset, rdx, rcx, kDontSaveFPRegs);
2862 2866
2863 __ bind(&done); 2867 __ bind(&done);
2864 context()->Plug(rax); 2868 context()->Plug(rax);
2865 } 2869 }
2866 2870
2867 2871
2868 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { 2872 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
2869 ASSERT_EQ(args->length(), 1); 2873 ASSERT_EQ(args->length(), 1);
2870 2874
2871 // Load the argument on the stack and call the stub. 2875 // Load the argument on the stack and call the stub.
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
3137 3141
3138 // Swap elements. Use object and temp as scratch registers. 3142 // Swap elements. Use object and temp as scratch registers.
3139 __ movq(object, Operand(index_1, 0)); 3143 __ movq(object, Operand(index_1, 0));
3140 __ movq(temp, Operand(index_2, 0)); 3144 __ movq(temp, Operand(index_2, 0));
3141 __ movq(Operand(index_2, 0), object); 3145 __ movq(Operand(index_2, 0), object);
3142 __ movq(Operand(index_1, 0), temp); 3146 __ movq(Operand(index_1, 0), temp);
3143 3147
3144 Label new_space; 3148 Label new_space;
3145 __ InNewSpace(elements, temp, equal, &new_space); 3149 __ InNewSpace(elements, temp, equal, &new_space);
3146 3150
3147 __ movq(object, elements); 3151 // Since we are swapping two objects, the incremental marker is not disturbed,
3148 __ RecordWriteHelper(object, index_1, temp, kDontSaveFPRegs); 3152 // so we don't call the stub that handles this.
3149 __ RecordWriteHelper(elements, index_2, temp, kDontSaveFPRegs); 3153 __ RememberedSetHelper(
3154 index_1, temp, kDontSaveFPRegs, MacroAssembler::kFallThroughAtEnd);
3155 __ RememberedSetHelper(
3156 index_2, temp, kDontSaveFPRegs, MacroAssembler::kFallThroughAtEnd);
3150 3157
3151 __ bind(&new_space); 3158 __ bind(&new_space);
3152 // We are done. Drop elements from the stack, and return undefined. 3159 // We are done. Drop elements from the stack, and return undefined.
3153 __ addq(rsp, Immediate(3 * kPointerSize)); 3160 __ addq(rsp, Immediate(3 * kPointerSize));
3154 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 3161 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
3155 __ jmp(&done); 3162 __ jmp(&done);
3156 3163
3157 __ bind(&slow_case); 3164 __ bind(&slow_case);
3158 __ CallRuntime(Runtime::kSwapElements, 3); 3165 __ CallRuntime(Runtime::kSwapElements, 3);
3159 3166
(...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after
4311 __ ret(0); 4318 __ ret(0);
4312 } 4319 }
4313 4320
4314 4321
4315 #undef __ 4322 #undef __
4316 4323
4317 4324
4318 } } // namespace v8::internal 4325 } } // namespace v8::internal
4319 4326
4320 #endif // V8_TARGET_ARCH_X64 4327 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.cc ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698