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

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

Issue 7945009: Merge experimental/gc branch to the bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 3 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/deoptimizer-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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 for (int i = 0; i < num_parameters; i++) { 193 for (int i = 0; i < num_parameters; i++) {
194 Variable* var = scope()->parameter(i); 194 Variable* var = scope()->parameter(i);
195 if (var->IsContextSlot()) { 195 if (var->IsContextSlot()) {
196 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 196 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
197 (num_parameters - 1 - i) * kPointerSize; 197 (num_parameters - 1 - i) * kPointerSize;
198 // Load parameter from stack. 198 // Load parameter from stack.
199 __ movq(rax, Operand(rbp, parameter_offset)); 199 __ movq(rax, Operand(rbp, parameter_offset));
200 // Store it in the context. 200 // Store it in the context.
201 int context_offset = Context::SlotOffset(var->index()); 201 int context_offset = Context::SlotOffset(var->index());
202 __ movq(Operand(rsi, context_offset), rax); 202 __ movq(Operand(rsi, context_offset), rax);
203 // Update the write barrier. This clobbers all involved 203 // Update the write barrier. This clobbers rax and rbx.
204 // registers, so we have use a third register to avoid 204 __ RecordWriteContextSlot(
205 // clobbering rsi. 205 rsi, context_offset, rax, rbx, kDontSaveFPRegs);
206 __ movq(rcx, rsi);
207 __ RecordWrite(rcx, context_offset, rax, rbx);
208 } 206 }
209 } 207 }
210 } 208 }
211 209
212 // Possibly allocate an arguments object. 210 // Possibly allocate an arguments object.
213 Variable* arguments = scope()->arguments(); 211 Variable* arguments = scope()->arguments();
214 if (arguments != NULL) { 212 if (arguments != NULL) {
215 // Arguments object must be allocated after the context object, in 213 // Arguments object must be allocated after the context object, in
216 // case the "arguments" or ".arguments" variables are in the context. 214 // case the "arguments" or ".arguments" variables are in the context.
217 Comment cmnt(masm_, "[ Allocate arguments object"); 215 Comment cmnt(masm_, "[ Allocate arguments object");
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 void FullCodeGenerator::SetVar(Variable* var, 634 void FullCodeGenerator::SetVar(Variable* var,
637 Register src, 635 Register src,
638 Register scratch0, 636 Register scratch0,
639 Register scratch1) { 637 Register scratch1) {
640 ASSERT(var->IsContextSlot() || var->IsStackAllocated()); 638 ASSERT(var->IsContextSlot() || var->IsStackAllocated());
641 ASSERT(!scratch0.is(src)); 639 ASSERT(!scratch0.is(src));
642 ASSERT(!scratch0.is(scratch1)); 640 ASSERT(!scratch0.is(scratch1));
643 ASSERT(!scratch1.is(src)); 641 ASSERT(!scratch1.is(src));
644 MemOperand location = VarOperand(var, scratch0); 642 MemOperand location = VarOperand(var, scratch0);
645 __ movq(location, src); 643 __ movq(location, src);
644
646 // Emit the write barrier code if the location is in the heap. 645 // Emit the write barrier code if the location is in the heap.
647 if (var->IsContextSlot()) { 646 if (var->IsContextSlot()) {
648 int offset = Context::SlotOffset(var->index()); 647 int offset = Context::SlotOffset(var->index());
649 __ RecordWrite(scratch0, offset, src, scratch1); 648 __ RecordWriteContextSlot(scratch0, offset, src, scratch1, kDontSaveFPRegs);
650 } 649 }
651 } 650 }
652 651
653 652
654 void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state, 653 void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state,
655 bool should_normalize, 654 bool should_normalize,
656 Label* if_true, 655 Label* if_true,
657 Label* if_false) { 656 Label* if_false) {
658 // Only prepare for bailouts before splits if we're in a test 657 // Only prepare for bailouts before splits if we're in a test
659 // context. Otherwise, we let the Visit function deal with the 658 // context. Otherwise, we let the Visit function deal with the
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 __ CompareRoot(rbx, Heap::kWithContextMapRootIndex); 712 __ CompareRoot(rbx, Heap::kWithContextMapRootIndex);
714 __ Check(not_equal, "Declaration in with context."); 713 __ Check(not_equal, "Declaration in with context.");
715 __ CompareRoot(rbx, Heap::kCatchContextMapRootIndex); 714 __ CompareRoot(rbx, Heap::kCatchContextMapRootIndex);
716 __ Check(not_equal, "Declaration in catch context."); 715 __ Check(not_equal, "Declaration in catch context.");
717 } 716 }
718 if (function != NULL) { 717 if (function != NULL) {
719 Comment cmnt(masm_, "[ Declaration"); 718 Comment cmnt(masm_, "[ Declaration");
720 VisitForAccumulatorValue(function); 719 VisitForAccumulatorValue(function);
721 __ movq(ContextOperand(rsi, variable->index()), result_register()); 720 __ movq(ContextOperand(rsi, variable->index()), result_register());
722 int offset = Context::SlotOffset(variable->index()); 721 int offset = Context::SlotOffset(variable->index());
723 __ movq(rbx, rsi); 722 // We know that we have written a function, which is not a smi.
724 __ RecordWrite(rbx, offset, result_register(), rcx); 723 __ RecordWriteContextSlot(rsi,
724 offset,
725 result_register(),
726 rcx,
727 kDontSaveFPRegs,
728 EMIT_REMEMBERED_SET,
729 OMIT_SMI_CHECK);
725 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 730 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
726 } else if (mode == Variable::CONST || mode == Variable::LET) { 731 } else if (mode == Variable::CONST || mode == Variable::LET) {
727 Comment cmnt(masm_, "[ Declaration"); 732 Comment cmnt(masm_, "[ Declaration");
728 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 733 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
729 __ movq(ContextOperand(rsi, variable->index()), kScratchRegister); 734 __ movq(ContextOperand(rsi, variable->index()), kScratchRegister);
730 // No write barrier since the hole value is in old space. 735 // No write barrier since the hole value is in old space.
731 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 736 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
732 } 737 }
733 break; 738 break;
734 739
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 } 1454 }
1450 VisitForAccumulatorValue(subexpr); 1455 VisitForAccumulatorValue(subexpr);
1451 1456
1452 // Store the subexpression value in the array's elements. 1457 // Store the subexpression value in the array's elements.
1453 __ movq(rbx, Operand(rsp, 0)); // Copy of array literal. 1458 __ movq(rbx, Operand(rsp, 0)); // Copy of array literal.
1454 __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); 1459 __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset));
1455 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1460 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1456 __ movq(FieldOperand(rbx, offset), result_register()); 1461 __ movq(FieldOperand(rbx, offset), result_register());
1457 1462
1458 // Update the write barrier for the array store. 1463 // Update the write barrier for the array store.
1459 __ RecordWrite(rbx, offset, result_register(), rcx); 1464 __ RecordWriteField(rbx, offset, result_register(), rcx, kDontSaveFPRegs);
1460 1465
1461 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1466 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
1462 } 1467 }
1463 1468
1464 if (result_saved) { 1469 if (result_saved) {
1465 context()->PlugTOS(); 1470 context()->PlugTOS();
1466 } else { 1471 } else {
1467 context()->Plug(rax); 1472 context()->Plug(rax);
1468 } 1473 }
1469 } 1474 }
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 MemOperand location = VarOperand(var, rcx); 1780 MemOperand location = VarOperand(var, rcx);
1776 __ movq(rdx, location); 1781 __ movq(rdx, location);
1777 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 1782 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1778 __ j(not_equal, &assign, Label::kNear); 1783 __ j(not_equal, &assign, Label::kNear);
1779 __ Push(var->name()); 1784 __ Push(var->name());
1780 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1785 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1781 __ bind(&assign); 1786 __ bind(&assign);
1782 __ movq(location, rax); 1787 __ movq(location, rax);
1783 if (var->IsContextSlot()) { 1788 if (var->IsContextSlot()) {
1784 __ movq(rdx, rax); 1789 __ movq(rdx, rax);
1785 __ RecordWrite(rcx, Context::SlotOffset(var->index()), rdx, rbx); 1790 __ RecordWriteContextSlot(
1791 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs);
1786 } 1792 }
1787 } 1793 }
1788 1794
1789 } else if (var->mode() != Variable::CONST) { 1795 } else if (var->mode() != Variable::CONST) {
1790 // Assignment to var or initializing assignment to let. 1796 // Assignment to var or initializing assignment to let.
1791 if (var->IsStackAllocated() || var->IsContextSlot()) { 1797 if (var->IsStackAllocated() || var->IsContextSlot()) {
1792 MemOperand location = VarOperand(var, rcx); 1798 MemOperand location = VarOperand(var, rcx);
1793 if (FLAG_debug_code && op == Token::INIT_LET) { 1799 if (FLAG_debug_code && op == Token::INIT_LET) {
1794 // Check for an uninitialized let binding. 1800 // Check for an uninitialized let binding.
1795 __ movq(rdx, location); 1801 __ movq(rdx, location);
1796 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 1802 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1797 __ Check(equal, "Let binding re-initialization."); 1803 __ Check(equal, "Let binding re-initialization.");
1798 } 1804 }
1799 // Perform the assignment. 1805 // Perform the assignment.
1800 __ movq(location, rax); 1806 __ movq(location, rax);
1801 if (var->IsContextSlot()) { 1807 if (var->IsContextSlot()) {
1802 __ movq(rdx, rax); 1808 __ movq(rdx, rax);
1803 __ RecordWrite(rcx, Context::SlotOffset(var->index()), rdx, rbx); 1809 __ RecordWriteContextSlot(
1810 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs);
1804 } 1811 }
1805 } else { 1812 } else {
1806 ASSERT(var->IsLookupSlot()); 1813 ASSERT(var->IsLookupSlot());
1807 __ push(rax); // Value. 1814 __ push(rax); // Value.
1808 __ push(rsi); // Context. 1815 __ push(rsi); // Context.
1809 __ Push(var->name()); 1816 __ Push(var->name());
1810 __ Push(Smi::FromInt(strict_mode_flag())); 1817 __ Push(Smi::FromInt(strict_mode_flag()));
1811 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1818 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1812 } 1819 }
1813 } 1820 }
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after
2724 2731
2725 // If the object is not a value type, return the value. 2732 // If the object is not a value type, return the value.
2726 __ CmpObjectType(rbx, JS_VALUE_TYPE, rcx); 2733 __ CmpObjectType(rbx, JS_VALUE_TYPE, rcx);
2727 __ j(not_equal, &done); 2734 __ j(not_equal, &done);
2728 2735
2729 // Store the value. 2736 // Store the value.
2730 __ movq(FieldOperand(rbx, JSValue::kValueOffset), rax); 2737 __ movq(FieldOperand(rbx, JSValue::kValueOffset), rax);
2731 // Update the write barrier. Save the value as it will be 2738 // Update the write barrier. Save the value as it will be
2732 // overwritten by the write barrier code and is needed afterward. 2739 // overwritten by the write barrier code and is needed afterward.
2733 __ movq(rdx, rax); 2740 __ movq(rdx, rax);
2734 __ RecordWrite(rbx, JSValue::kValueOffset, rdx, rcx); 2741 __ RecordWriteField(rbx, JSValue::kValueOffset, rdx, rcx, kDontSaveFPRegs);
2735 2742
2736 __ bind(&done); 2743 __ bind(&done);
2737 context()->Plug(rax); 2744 context()->Plug(rax);
2738 } 2745 }
2739 2746
2740 2747
2741 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { 2748 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
2742 ASSERT_EQ(args->length(), 1); 2749 ASSERT_EQ(args->length(), 1);
2743 2750
2744 // Load the argument on the stack and call the stub. 2751 // Load the argument on the stack and call the stub.
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
3008 FixedArray::kHeaderSize)); 3015 FixedArray::kHeaderSize));
3009 __ lea(index_2, FieldOperand(elements, index_2, times_pointer_size, 3016 __ lea(index_2, FieldOperand(elements, index_2, times_pointer_size,
3010 FixedArray::kHeaderSize)); 3017 FixedArray::kHeaderSize));
3011 3018
3012 // Swap elements. Use object and temp as scratch registers. 3019 // Swap elements. Use object and temp as scratch registers.
3013 __ movq(object, Operand(index_1, 0)); 3020 __ movq(object, Operand(index_1, 0));
3014 __ movq(temp, Operand(index_2, 0)); 3021 __ movq(temp, Operand(index_2, 0));
3015 __ movq(Operand(index_2, 0), object); 3022 __ movq(Operand(index_2, 0), object);
3016 __ movq(Operand(index_1, 0), temp); 3023 __ movq(Operand(index_1, 0), temp);
3017 3024
3018 Label new_space; 3025 Label no_remembered_set;
3019 __ InNewSpace(elements, temp, equal, &new_space); 3026 __ CheckPageFlag(elements,
3027 temp,
3028 1 << MemoryChunk::SCAN_ON_SCAVENGE,
3029 not_zero,
3030 &no_remembered_set,
3031 Label::kNear);
3032 // Possible optimization: do a check that both values are Smis
3033 // (or them and test against Smi mask.)
3020 3034
3021 __ movq(object, elements); 3035 // We are swapping two objects in an array and the incremental marker never
3022 __ RecordWriteHelper(object, index_1, temp); 3036 // pauses in the middle of scanning a single object. Therefore the
3023 __ RecordWriteHelper(elements, index_2, temp); 3037 // incremental marker is not disturbed, so we don't need to call the
3038 // RecordWrite stub that notifies the incremental marker.
3039 __ RememberedSetHelper(
3040 index_1, temp, kDontSaveFPRegs, MacroAssembler::kFallThroughAtEnd);
3041 __ RememberedSetHelper(
3042 index_2, temp, kDontSaveFPRegs, MacroAssembler::kFallThroughAtEnd);
3024 3043
3025 __ bind(&new_space); 3044 __ bind(&no_remembered_set);
3045
3026 // We are done. Drop elements from the stack, and return undefined. 3046 // We are done. Drop elements from the stack, and return undefined.
3027 __ addq(rsp, Immediate(3 * kPointerSize)); 3047 __ addq(rsp, Immediate(3 * kPointerSize));
3028 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 3048 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
3029 __ jmp(&done); 3049 __ jmp(&done);
3030 3050
3031 __ bind(&slow_case); 3051 __ bind(&slow_case);
3032 __ CallRuntime(Runtime::kSwapElements, 3); 3052 __ CallRuntime(Runtime::kSwapElements, 3);
3033 3053
3034 __ bind(&done); 3054 __ bind(&done);
3035 context()->Plug(rax); 3055 context()->Plug(rax);
(...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after
4153 *context_length = 0; 4173 *context_length = 0;
4154 return previous_; 4174 return previous_;
4155 } 4175 }
4156 4176
4157 4177
4158 #undef __ 4178 #undef __
4159 4179
4160 } } // namespace v8::internal 4180 } } // namespace v8::internal
4161 4181
4162 #endif // V8_TARGET_ARCH_X64 4182 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/deoptimizer-x64.cc ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698