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

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

Issue 6581029: X64: Port r6635 and r6659... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 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 | « no previous file | src/x64/macro-assembler-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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 // stack frame was an arguments adapter frame. 200 // stack frame was an arguments adapter frame.
201 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); 201 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
202 __ CallStub(&stub); 202 __ CallStub(&stub);
203 // Store new arguments object in both "arguments" and ".arguments" slots. 203 // Store new arguments object in both "arguments" and ".arguments" slots.
204 __ movq(rcx, rax); 204 __ movq(rcx, rax);
205 Move(arguments->AsSlot(), rax, rbx, rdx); 205 Move(arguments->AsSlot(), rax, rbx, rdx);
206 Slot* dot_arguments_slot = scope()->arguments_shadow()->AsSlot(); 206 Slot* dot_arguments_slot = scope()->arguments_shadow()->AsSlot();
207 Move(dot_arguments_slot, rcx, rbx, rdx); 207 Move(dot_arguments_slot, rcx, rbx, rdx);
208 } 208 }
209 209
210 { Comment cmnt(masm_, "[ Declarations");
211 // For named function expressions, declare the function name as a
212 // constant.
213 if (scope()->is_function_scope() && scope()->function() != NULL) {
214 EmitDeclaration(scope()->function(), Variable::CONST, NULL);
215 }
216 // Visit all the explicit declarations unless there is an illegal
217 // redeclaration.
218 if (scope()->HasIllegalRedeclaration()) {
219 scope()->VisitIllegalRedeclaration(this);
220 } else {
221 VisitDeclarations(scope()->declarations());
222 }
223 }
224
225 if (FLAG_trace) { 210 if (FLAG_trace) {
226 __ CallRuntime(Runtime::kTraceEnter, 0); 211 __ CallRuntime(Runtime::kTraceEnter, 0);
227 } 212 }
228 213
229 { Comment cmnt(masm_, "[ Stack check"); 214 // Visit the declarations and body unless there is an illegal
230 PrepareForBailout(info->function(), NO_REGISTERS); 215 // redeclaration.
231 NearLabel ok; 216 if (scope()->HasIllegalRedeclaration()) {
232 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 217 Comment cmnt(masm_, "[ Declarations");
233 __ j(above_equal, &ok); 218 scope()->VisitIllegalRedeclaration(this);
234 StackCheckStub stub; 219 } else {
235 __ CallStub(&stub); 220 { Comment cmnt(masm_, "[ Declarations");
236 __ bind(&ok); 221 // For named function expressions, declare the function name as a
222 // constant.
223 if (scope()->is_function_scope() && scope()->function() != NULL) {
224 EmitDeclaration(scope()->function(), Variable::CONST, NULL);
225 }
226 VisitDeclarations(scope()->declarations());
227 }
228
229 { Comment cmnt(masm_, "[ Stack check");
230 PrepareForBailout(info->function(), NO_REGISTERS);
231 NearLabel ok;
232 __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
233 __ j(above_equal, &ok);
234 StackCheckStub stub;
235 __ CallStub(&stub);
236 __ bind(&ok);
237 }
238
239 { Comment cmnt(masm_, "[ Body");
240 ASSERT(loop_depth() == 0);
241 VisitStatements(function()->body());
242 ASSERT(loop_depth() == 0);
243 }
237 } 244 }
238 245
239 { Comment cmnt(masm_, "[ Body"); 246 // Always emit a 'return undefined' in case control fell off the end of
240 ASSERT(loop_depth() == 0); 247 // the body.
241 VisitStatements(function()->body());
242 ASSERT(loop_depth() == 0);
243 }
244
245 { Comment cmnt(masm_, "[ return <undefined>;"); 248 { Comment cmnt(masm_, "[ return <undefined>;");
246 // Emit a 'return undefined' in case control fell off the end of the body.
247 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 249 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
248 EmitReturnSequence(); 250 EmitReturnSequence();
249 } 251 }
250 } 252 }
251 253
252 254
253 void FullCodeGenerator::ClearAccumulator() { 255 void FullCodeGenerator::ClearAccumulator() {
254 __ Set(rax, 0); 256 __ Set(rax, 0);
255 } 257 }
256 258
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 } 1077 }
1076 __ movq(temp, ContextOperand(context, Context::CLOSURE_INDEX)); 1078 __ movq(temp, ContextOperand(context, Context::CLOSURE_INDEX));
1077 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset)); 1079 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset));
1078 // Walk the rest of the chain without clobbering rsi. 1080 // Walk the rest of the chain without clobbering rsi.
1079 context = temp; 1081 context = temp;
1080 } 1082 }
1081 } 1083 }
1082 // Check that last extension is NULL. 1084 // Check that last extension is NULL.
1083 __ cmpq(ContextOperand(context, Context::EXTENSION_INDEX), Immediate(0)); 1085 __ cmpq(ContextOperand(context, Context::EXTENSION_INDEX), Immediate(0));
1084 __ j(not_equal, slow); 1086 __ j(not_equal, slow);
1085 __ movq(temp, ContextOperand(context, Context::FCONTEXT_INDEX)); 1087
1088 // This function is used only for loads, not stores, so it's safe to
1089 // return an rsi-based operand (the write barrier cannot be allowed to
1090 // destroy the rsi register).
1086 return ContextOperand(temp, slot->index()); 1091 return ContextOperand(temp, slot->index());
1087 } 1092 }
1088 1093
1089 1094
1090 void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase( 1095 void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
1091 Slot* slot, 1096 Slot* slot,
1092 TypeofState typeof_state, 1097 TypeofState typeof_state,
1093 Label* slow, 1098 Label* slow,
1094 Label* done) { 1099 Label* done) {
1095 // Generate fast-case code for variables that might be shadowed by 1100 // Generate fast-case code for variables that might be shadowed by
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 // Assignment to a global variable. Use inline caching for the 1728 // Assignment to a global variable. Use inline caching for the
1724 // assignment. Right-hand-side value is passed in rax, variable name in 1729 // assignment. Right-hand-side value is passed in rax, variable name in
1725 // rcx, and the global object on the stack. 1730 // rcx, and the global object on the stack.
1726 __ Move(rcx, var->name()); 1731 __ Move(rcx, var->name());
1727 __ movq(rdx, GlobalObjectOperand()); 1732 __ movq(rdx, GlobalObjectOperand());
1728 Handle<Code> ic(Builtins::builtin(is_strict() 1733 Handle<Code> ic(Builtins::builtin(is_strict()
1729 ? Builtins::StoreIC_Initialize_Strict 1734 ? Builtins::StoreIC_Initialize_Strict
1730 : Builtins::StoreIC_Initialize)); 1735 : Builtins::StoreIC_Initialize));
1731 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1736 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1732 1737
1733 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { 1738 } else if (op == Token::INIT_CONST) {
1734 // Perform the assignment for non-const variables and for initialization 1739 // Like var declarations, const declarations are hoisted to function
1735 // of const variables. Const assignments are simply skipped. 1740 // scope. However, unlike var initializers, const initializers are able
1736 Label done; 1741 // to drill a hole to that function context, even from inside a 'with'
1742 // context. We thus bypass the normal static scope lookup.
1743 Slot* slot = var->AsSlot();
1744 Label skip;
1745 switch (slot->type()) {
1746 case Slot::PARAMETER:
1747 // No const parameters.
1748 UNREACHABLE();
1749 break;
1750 case Slot::LOCAL:
1751 __ movq(rdx, Operand(rbp, SlotOffset(slot)));
1752 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1753 __ j(not_equal, &skip);
1754 __ movq(Operand(rbp, SlotOffset(slot)), rax);
1755 break;
1756 case Slot::CONTEXT: {
1757 __ movq(rcx, ContextOperand(rsi, Context::FCONTEXT_INDEX));
1758 __ movq(rdx, ContextOperand(rcx, slot->index()));
1759 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1760 __ j(not_equal, &skip);
1761 __ movq(ContextOperand(rcx, slot->index()), rax);
1762 int offset = Context::SlotOffset(slot->index());
1763 __ movq(rdx, rax); // Preserve the stored value in eax.
1764 __ RecordWrite(rcx, offset, rdx, rbx);
1765 break;
1766 }
1767 case Slot::LOOKUP:
1768 __ push(rax);
1769 __ push(rsi);
1770 __ Push(var->name());
1771 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1772 break;
1773 }
1774 __ bind(&skip);
1775
1776 } else if (var->mode() != Variable::CONST) {
1777 // Perform the assignment for non-const variables. Const assignments
1778 // are simply skipped.
1737 Slot* slot = var->AsSlot(); 1779 Slot* slot = var->AsSlot();
1738 switch (slot->type()) { 1780 switch (slot->type()) {
1739 case Slot::PARAMETER: 1781 case Slot::PARAMETER:
1740 case Slot::LOCAL: 1782 case Slot::LOCAL:
1741 if (op == Token::INIT_CONST) {
1742 // Detect const reinitialization by checking for the hole value.
1743 __ movq(rdx, Operand(rbp, SlotOffset(slot)));
1744 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1745 __ j(not_equal, &done);
1746 }
1747 // Perform the assignment. 1783 // Perform the assignment.
1748 __ movq(Operand(rbp, SlotOffset(slot)), rax); 1784 __ movq(Operand(rbp, SlotOffset(slot)), rax);
1749 break; 1785 break;
1750 1786
1751 case Slot::CONTEXT: { 1787 case Slot::CONTEXT: {
1752 MemOperand target = EmitSlotSearch(slot, rcx); 1788 MemOperand target = EmitSlotSearch(slot, rcx);
1753 if (op == Token::INIT_CONST) {
1754 // Detect const reinitialization by checking for the hole value.
1755 __ movq(rdx, target);
1756 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1757 __ j(not_equal, &done);
1758 }
1759 // Perform the assignment and issue the write barrier. 1789 // Perform the assignment and issue the write barrier.
1760 __ movq(target, rax); 1790 __ movq(target, rax);
1761 // The value of the assignment is in rax. RecordWrite clobbers its 1791 // The value of the assignment is in rax. RecordWrite clobbers its
1762 // register arguments. 1792 // register arguments.
1763 __ movq(rdx, rax); 1793 __ movq(rdx, rax);
1764 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; 1794 int offset = Context::SlotOffset(slot->index());
1765 __ RecordWrite(rcx, offset, rdx, rbx); 1795 __ RecordWrite(rcx, offset, rdx, rbx);
1766 break; 1796 break;
1767 } 1797 }
1768 1798
1769 case Slot::LOOKUP: 1799 case Slot::LOOKUP:
1770 // Call the runtime for the assignment. The runtime will ignore 1800 // Call the runtime for the assignment.
1771 // const reinitialization.
1772 __ push(rax); // Value. 1801 __ push(rax); // Value.
1773 __ push(rsi); // Context. 1802 __ push(rsi); // Context.
1774 __ Push(var->name()); 1803 __ Push(var->name());
1775 if (op == Token::INIT_CONST) { 1804 __ CallRuntime(Runtime::kStoreContextSlot, 3);
1776 // The runtime will ignore const redeclaration.
1777 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1778 } else {
1779 __ CallRuntime(Runtime::kStoreContextSlot, 3);
1780 }
1781 break; 1805 break;
1782 } 1806 }
1783 __ bind(&done);
1784 } 1807 }
1785 } 1808 }
1786 1809
1787 1810
1788 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1811 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1789 // Assignment to a property, using a named store IC. 1812 // Assignment to a property, using a named store IC.
1790 Property* prop = expr->target()->AsProperty(); 1813 Property* prop = expr->target()->AsProperty();
1791 ASSERT(prop != NULL); 1814 ASSERT(prop != NULL);
1792 ASSERT(prop->key()->AsLiteral() != NULL); 1815 ASSERT(prop->key()->AsLiteral() != NULL);
1793 1816
(...skipping 1974 matching lines...) Expand 10 before | Expand all | Expand 10 after
3768 __ ret(0); 3791 __ ret(0);
3769 } 3792 }
3770 3793
3771 3794
3772 #undef __ 3795 #undef __
3773 3796
3774 3797
3775 } } // namespace v8::internal 3798 } } // namespace v8::internal
3776 3799
3777 #endif // V8_TARGET_ARCH_X64 3800 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « no previous file | src/x64/macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698