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

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

Issue 8221004: Move declaration of SerializedScopeInfo from variables.h to objects.h (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 2 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
« src/parser.cc ('K') | « src/variables.cc ('k') | no next file » | 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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 Comment cmnt(masm_, "[ Declarations"); 247 Comment cmnt(masm_, "[ Declarations");
248 scope()->VisitIllegalRedeclaration(this); 248 scope()->VisitIllegalRedeclaration(this);
249 249
250 } else { 250 } else {
251 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS); 251 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
252 { Comment cmnt(masm_, "[ Declarations"); 252 { Comment cmnt(masm_, "[ Declarations");
253 // For named function expressions, declare the function name as a 253 // For named function expressions, declare the function name as a
254 // constant. 254 // constant.
255 if (scope()->is_function_scope() && scope()->function() != NULL) { 255 if (scope()->is_function_scope() && scope()->function() != NULL) {
256 int ignored = 0; 256 int ignored = 0;
257 EmitDeclaration(scope()->function(), Variable::CONST, NULL, &ignored); 257 EmitDeclaration(scope()->function(), CONST, NULL, &ignored);
258 } 258 }
259 VisitDeclarations(scope()->declarations()); 259 VisitDeclarations(scope()->declarations());
260 } 260 }
261 261
262 { Comment cmnt(masm_, "[ Stack check"); 262 { Comment cmnt(masm_, "[ Stack check");
263 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS); 263 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
264 Label ok; 264 Label ok;
265 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 265 __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
266 __ j(above_equal, &ok, Label::kNear); 266 __ j(above_equal, &ok, Label::kNear);
267 StackCheckStub stub; 267 StackCheckStub stub;
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 670
671 if (should_normalize) { 671 if (should_normalize) {
672 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 672 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
673 Split(equal, if_true, if_false, NULL); 673 Split(equal, if_true, if_false, NULL);
674 __ bind(&skip); 674 __ bind(&skip);
675 } 675 }
676 } 676 }
677 677
678 678
679 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, 679 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
680 Variable::Mode mode, 680 VariableMode mode,
681 FunctionLiteral* function, 681 FunctionLiteral* function,
682 int* global_count) { 682 int* global_count) {
683 // If it was not possible to allocate the variable at compile time, we 683 // If it was not possible to allocate the variable at compile time, we
684 // need to "declare" it at runtime to make sure it actually exists in the 684 // need to "declare" it at runtime to make sure it actually exists in the
685 // local context. 685 // local context.
686 Variable* variable = proxy->var(); 686 Variable* variable = proxy->var();
687 switch (variable->location()) { 687 switch (variable->location()) {
688 case Variable::UNALLOCATED: 688 case Variable::UNALLOCATED:
689 ++(*global_count); 689 ++(*global_count);
690 break; 690 break;
691 691
692 case Variable::PARAMETER: 692 case Variable::PARAMETER:
693 case Variable::LOCAL: 693 case Variable::LOCAL:
694 if (function != NULL) { 694 if (function != NULL) {
695 Comment cmnt(masm_, "[ Declaration"); 695 Comment cmnt(masm_, "[ Declaration");
696 VisitForAccumulatorValue(function); 696 VisitForAccumulatorValue(function);
697 __ movq(StackOperand(variable), result_register()); 697 __ movq(StackOperand(variable), result_register());
698 } else if (mode == Variable::CONST || mode == Variable::LET) { 698 } else if (mode == CONST || mode == LET) {
699 Comment cmnt(masm_, "[ Declaration"); 699 Comment cmnt(masm_, "[ Declaration");
700 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 700 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
701 __ movq(StackOperand(variable), kScratchRegister); 701 __ movq(StackOperand(variable), kScratchRegister);
702 } 702 }
703 break; 703 break;
704 704
705 case Variable::CONTEXT: 705 case Variable::CONTEXT:
706 // The variable in the decl always resides in the current function 706 // The variable in the decl always resides in the current function
707 // context. 707 // context.
708 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); 708 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
(...skipping 12 matching lines...) Expand all
721 int offset = Context::SlotOffset(variable->index()); 721 int offset = Context::SlotOffset(variable->index());
722 // We know that we have written a function, which is not a smi. 722 // We know that we have written a function, which is not a smi.
723 __ RecordWriteContextSlot(rsi, 723 __ RecordWriteContextSlot(rsi,
724 offset, 724 offset,
725 result_register(), 725 result_register(),
726 rcx, 726 rcx,
727 kDontSaveFPRegs, 727 kDontSaveFPRegs,
728 EMIT_REMEMBERED_SET, 728 EMIT_REMEMBERED_SET,
729 OMIT_SMI_CHECK); 729 OMIT_SMI_CHECK);
730 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 730 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
731 } else if (mode == Variable::CONST || mode == Variable::LET) { 731 } else if (mode == CONST || mode == LET) {
732 Comment cmnt(masm_, "[ Declaration"); 732 Comment cmnt(masm_, "[ Declaration");
733 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 733 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
734 __ movq(ContextOperand(rsi, variable->index()), kScratchRegister); 734 __ movq(ContextOperand(rsi, variable->index()), kScratchRegister);
735 // No write barrier since the hole value is in old space. 735 // No write barrier since the hole value is in old space.
736 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 736 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
737 } 737 }
738 break; 738 break;
739 739
740 case Variable::LOOKUP: { 740 case Variable::LOOKUP: {
741 Comment cmnt(masm_, "[ Declaration"); 741 Comment cmnt(masm_, "[ Declaration");
742 __ push(rsi); 742 __ push(rsi);
743 __ Push(variable->name()); 743 __ Push(variable->name());
744 // Declaration nodes are always introduced in one of three modes. 744 // Declaration nodes are always introduced in one of three modes.
745 ASSERT(mode == Variable::VAR || 745 ASSERT(mode == VAR || mode == CONST || mode == LET);
746 mode == Variable::CONST || 746 PropertyAttributes attr = (mode == CONST) ? READ_ONLY : NONE;
747 mode == Variable::LET);
748 PropertyAttributes attr = (mode == Variable::CONST) ? READ_ONLY : NONE;
749 __ Push(Smi::FromInt(attr)); 747 __ Push(Smi::FromInt(attr));
750 // Push initial value, if any. 748 // Push initial value, if any.
751 // Note: For variables we must not push an initial value (such as 749 // Note: For variables we must not push an initial value (such as
752 // 'undefined') because we may have a (legal) redeclaration and we 750 // 'undefined') because we may have a (legal) redeclaration and we
753 // must not destroy the current value. 751 // must not destroy the current value.
754 if (function != NULL) { 752 if (function != NULL) {
755 VisitForStackValue(function); 753 VisitForStackValue(function);
756 } else if (mode == Variable::CONST || mode == Variable::LET) { 754 } else if (mode == CONST || mode == LET) {
757 __ PushRoot(Heap::kTheHoleValueRootIndex); 755 __ PushRoot(Heap::kTheHoleValueRootIndex);
758 } else { 756 } else {
759 __ Push(Smi::FromInt(0)); // Indicates no initial value. 757 __ Push(Smi::FromInt(0)); // Indicates no initial value.
760 } 758 }
761 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 759 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
762 break; 760 break;
763 } 761 }
764 } 762 }
765 } 763 }
766 764
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 1169
1172 void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var, 1170 void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var,
1173 TypeofState typeof_state, 1171 TypeofState typeof_state,
1174 Label* slow, 1172 Label* slow,
1175 Label* done) { 1173 Label* done) {
1176 // Generate fast-case code for variables that might be shadowed by 1174 // Generate fast-case code for variables that might be shadowed by
1177 // eval-introduced variables. Eval is used a lot without 1175 // eval-introduced variables. Eval is used a lot without
1178 // introducing variables. In those cases, we do not want to 1176 // introducing variables. In those cases, we do not want to
1179 // perform a runtime call for all variables in the scope 1177 // perform a runtime call for all variables in the scope
1180 // containing the eval. 1178 // containing the eval.
1181 if (var->mode() == Variable::DYNAMIC_GLOBAL) { 1179 if (var->mode() == DYNAMIC_GLOBAL) {
1182 EmitLoadGlobalCheckExtensions(var, typeof_state, slow); 1180 EmitLoadGlobalCheckExtensions(var, typeof_state, slow);
1183 __ jmp(done); 1181 __ jmp(done);
1184 } else if (var->mode() == Variable::DYNAMIC_LOCAL) { 1182 } else if (var->mode() == DYNAMIC_LOCAL) {
1185 Variable* local = var->local_if_not_shadowed(); 1183 Variable* local = var->local_if_not_shadowed();
1186 __ movq(rax, ContextSlotOperandCheckExtensions(local, slow)); 1184 __ movq(rax, ContextSlotOperandCheckExtensions(local, slow));
1187 if (local->mode() == Variable::CONST || 1185 if (local->mode() == CONST || local->mode() == LET) {
1188 local->mode() == Variable::LET) {
1189 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); 1186 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
1190 __ j(not_equal, done); 1187 __ j(not_equal, done);
1191 if (local->mode() == Variable::CONST) { 1188 if (local->mode() == CONST) {
1192 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1189 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
1193 } else { // Variable::LET 1190 } else { // LET
1194 __ Push(var->name()); 1191 __ Push(var->name());
1195 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1192 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1196 } 1193 }
1197 } 1194 }
1198 __ jmp(done); 1195 __ jmp(done);
1199 } 1196 }
1200 } 1197 }
1201 1198
1202 1199
1203 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1200 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
(...skipping 13 matching lines...) Expand all
1217 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1214 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1218 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 1215 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
1219 context()->Plug(rax); 1216 context()->Plug(rax);
1220 break; 1217 break;
1221 } 1218 }
1222 1219
1223 case Variable::PARAMETER: 1220 case Variable::PARAMETER:
1224 case Variable::LOCAL: 1221 case Variable::LOCAL:
1225 case Variable::CONTEXT: { 1222 case Variable::CONTEXT: {
1226 Comment cmnt(masm_, var->IsContextSlot() ? "Context slot" : "Stack slot"); 1223 Comment cmnt(masm_, var->IsContextSlot() ? "Context slot" : "Stack slot");
1227 if (var->mode() != Variable::LET && var->mode() != Variable::CONST) { 1224 if (var->mode() != LET && var->mode() != CONST) {
1228 context()->Plug(var); 1225 context()->Plug(var);
1229 } else { 1226 } else {
1230 // Let and const need a read barrier. 1227 // Let and const need a read barrier.
1231 Label done; 1228 Label done;
1232 GetVar(rax, var); 1229 GetVar(rax, var);
1233 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); 1230 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
1234 __ j(not_equal, &done, Label::kNear); 1231 __ j(not_equal, &done, Label::kNear);
1235 if (var->mode() == Variable::LET) { 1232 if (var->mode() == LET) {
1236 __ Push(var->name()); 1233 __ Push(var->name());
1237 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1234 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1238 } else { // Variable::CONST 1235 } else { // CONST
1239 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1236 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
1240 } 1237 }
1241 __ bind(&done); 1238 __ bind(&done);
1242 context()->Plug(rax); 1239 context()->Plug(rax);
1243 } 1240 }
1244 break; 1241 break;
1245 } 1242 }
1246 1243
1247 case Variable::LOOKUP: { 1244 case Variable::LOOKUP: {
1248 Label done, slow; 1245 Label done, slow;
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 // scope. However, unlike var initializers, const initializers are 1772 // scope. However, unlike var initializers, const initializers are
1776 // able to drill a hole to that function context, even from inside a 1773 // able to drill a hole to that function context, even from inside a
1777 // 'with' context. We thus bypass the normal static scope lookup for 1774 // 'with' context. We thus bypass the normal static scope lookup for
1778 // var->IsContextSlot(). 1775 // var->IsContextSlot().
1779 __ push(rax); 1776 __ push(rax);
1780 __ push(rsi); 1777 __ push(rsi);
1781 __ Push(var->name()); 1778 __ Push(var->name());
1782 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 1779 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1783 } 1780 }
1784 1781
1785 } else if (var->mode() == Variable::LET && op != Token::INIT_LET) { 1782 } else if (var->mode() == LET && op != Token::INIT_LET) {
1786 // Non-initializing assignment to let variable needs a write barrier. 1783 // Non-initializing assignment to let variable needs a write barrier.
1787 if (var->IsLookupSlot()) { 1784 if (var->IsLookupSlot()) {
1788 __ push(rax); // Value. 1785 __ push(rax); // Value.
1789 __ push(rsi); // Context. 1786 __ push(rsi); // Context.
1790 __ Push(var->name()); 1787 __ Push(var->name());
1791 __ Push(Smi::FromInt(strict_mode_flag())); 1788 __ Push(Smi::FromInt(strict_mode_flag()));
1792 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1789 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1793 } else { 1790 } else {
1794 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 1791 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
1795 Label assign; 1792 Label assign;
1796 MemOperand location = VarOperand(var, rcx); 1793 MemOperand location = VarOperand(var, rcx);
1797 __ movq(rdx, location); 1794 __ movq(rdx, location);
1798 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 1795 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1799 __ j(not_equal, &assign, Label::kNear); 1796 __ j(not_equal, &assign, Label::kNear);
1800 __ Push(var->name()); 1797 __ Push(var->name());
1801 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1798 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1802 __ bind(&assign); 1799 __ bind(&assign);
1803 __ movq(location, rax); 1800 __ movq(location, rax);
1804 if (var->IsContextSlot()) { 1801 if (var->IsContextSlot()) {
1805 __ movq(rdx, rax); 1802 __ movq(rdx, rax);
1806 __ RecordWriteContextSlot( 1803 __ RecordWriteContextSlot(
1807 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); 1804 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs);
1808 } 1805 }
1809 } 1806 }
1810 1807
1811 } else if (var->mode() != Variable::CONST) { 1808 } else if (var->mode() != CONST) {
1812 // Assignment to var or initializing assignment to let. 1809 // Assignment to var or initializing assignment to let.
1813 if (var->IsStackAllocated() || var->IsContextSlot()) { 1810 if (var->IsStackAllocated() || var->IsContextSlot()) {
1814 MemOperand location = VarOperand(var, rcx); 1811 MemOperand location = VarOperand(var, rcx);
1815 if (FLAG_debug_code && op == Token::INIT_LET) { 1812 if (FLAG_debug_code && op == Token::INIT_LET) {
1816 // Check for an uninitialized let binding. 1813 // Check for an uninitialized let binding.
1817 __ movq(rdx, location); 1814 __ movq(rdx, location);
1818 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 1815 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1819 __ Check(equal, "Let binding re-initialization."); 1816 __ Check(equal, "Let binding re-initialization.");
1820 } 1817 }
1821 // Perform the assignment. 1818 // Perform the assignment.
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 for (int i = 0; i < arg_count; i++) { 2067 for (int i = 0; i < arg_count; i++) {
2071 VisitForStackValue(args->at(i)); 2068 VisitForStackValue(args->at(i));
2072 } 2069 }
2073 2070
2074 // If we know that eval can only be shadowed by eval-introduced 2071 // If we know that eval can only be shadowed by eval-introduced
2075 // variables we attempt to load the global eval function directly in 2072 // variables we attempt to load the global eval function directly in
2076 // generated code. If we succeed, there is no need to perform a 2073 // generated code. If we succeed, there is no need to perform a
2077 // context lookup in the runtime system. 2074 // context lookup in the runtime system.
2078 Label done; 2075 Label done;
2079 Variable* var = proxy->var(); 2076 Variable* var = proxy->var();
2080 if (!var->IsUnallocated() && var->mode() == Variable::DYNAMIC_GLOBAL) { 2077 if (!var->IsUnallocated() && var->mode() == DYNAMIC_GLOBAL) {
2081 Label slow; 2078 Label slow;
2082 EmitLoadGlobalCheckExtensions(var, NOT_INSIDE_TYPEOF, &slow); 2079 EmitLoadGlobalCheckExtensions(var, NOT_INSIDE_TYPEOF, &slow);
2083 // Push the function and resolve eval. 2080 // Push the function and resolve eval.
2084 __ push(rax); 2081 __ push(rax);
2085 EmitResolvePossiblyDirectEval(SKIP_CONTEXT_LOOKUP, arg_count); 2082 EmitResolvePossiblyDirectEval(SKIP_CONTEXT_LOOKUP, arg_count);
2086 __ jmp(&done); 2083 __ jmp(&done);
2087 __ bind(&slow); 2084 __ bind(&slow);
2088 } 2085 }
2089 2086
2090 // Push a copy of the function (found below the arguments) and resolve 2087 // Push a copy of the function (found below the arguments) and resolve
(...skipping 2109 matching lines...) Expand 10 before | Expand all | Expand 10 after
4200 *context_length = 0; 4197 *context_length = 0;
4201 return previous_; 4198 return previous_;
4202 } 4199 }
4203 4200
4204 4201
4205 #undef __ 4202 #undef __
4206 4203
4207 } } // namespace v8::internal 4204 } } // namespace v8::internal
4208 4205
4209 #endif // V8_TARGET_ARCH_X64 4206 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/parser.cc ('K') | « src/variables.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698