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

Side by Side Diff: src/ia32/full-codegen-ia32.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
« no previous file with comments | « src/hydrogen.cc ('k') | src/objects.h » ('j') | src/parser.cc » ('J')
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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 Comment cmnt(masm_, "[ Declarations"); 259 Comment cmnt(masm_, "[ Declarations");
260 scope()->VisitIllegalRedeclaration(this); 260 scope()->VisitIllegalRedeclaration(this);
261 261
262 } else { 262 } else {
263 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS); 263 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
264 { Comment cmnt(masm_, "[ Declarations"); 264 { Comment cmnt(masm_, "[ Declarations");
265 // For named function expressions, declare the function name as a 265 // For named function expressions, declare the function name as a
266 // constant. 266 // constant.
267 if (scope()->is_function_scope() && scope()->function() != NULL) { 267 if (scope()->is_function_scope() && scope()->function() != NULL) {
268 int ignored = 0; 268 int ignored = 0;
269 EmitDeclaration(scope()->function(), Variable::CONST, NULL, &ignored); 269 EmitDeclaration(scope()->function(), CONST, NULL, &ignored);
270 } 270 }
271 VisitDeclarations(scope()->declarations()); 271 VisitDeclarations(scope()->declarations());
272 } 272 }
273 273
274 { Comment cmnt(masm_, "[ Stack check"); 274 { Comment cmnt(masm_, "[ Stack check");
275 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS); 275 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
276 Label ok; 276 Label ok;
277 ExternalReference stack_limit = 277 ExternalReference stack_limit =
278 ExternalReference::address_of_stack_limit(isolate()); 278 ExternalReference::address_of_stack_limit(isolate());
279 __ cmp(esp, Operand::StaticVariable(stack_limit)); 279 __ cmp(esp, Operand::StaticVariable(stack_limit));
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 697
698 if (should_normalize) { 698 if (should_normalize) {
699 __ cmp(eax, isolate()->factory()->true_value()); 699 __ cmp(eax, isolate()->factory()->true_value());
700 Split(equal, if_true, if_false, NULL); 700 Split(equal, if_true, if_false, NULL);
701 __ bind(&skip); 701 __ bind(&skip);
702 } 702 }
703 } 703 }
704 704
705 705
706 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, 706 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
707 Variable::Mode mode, 707 VariableMode mode,
708 FunctionLiteral* function, 708 FunctionLiteral* function,
709 int* global_count) { 709 int* global_count) {
710 // If it was not possible to allocate the variable at compile time, we 710 // If it was not possible to allocate the variable at compile time, we
711 // need to "declare" it at runtime to make sure it actually exists in the 711 // need to "declare" it at runtime to make sure it actually exists in the
712 // local context. 712 // local context.
713 Variable* variable = proxy->var(); 713 Variable* variable = proxy->var();
714 switch (variable->location()) { 714 switch (variable->location()) {
715 case Variable::UNALLOCATED: 715 case Variable::UNALLOCATED:
716 ++(*global_count); 716 ++(*global_count);
717 break; 717 break;
718 718
719 case Variable::PARAMETER: 719 case Variable::PARAMETER:
720 case Variable::LOCAL: 720 case Variable::LOCAL:
721 if (function != NULL) { 721 if (function != NULL) {
722 Comment cmnt(masm_, "[ Declaration"); 722 Comment cmnt(masm_, "[ Declaration");
723 VisitForAccumulatorValue(function); 723 VisitForAccumulatorValue(function);
724 __ mov(StackOperand(variable), result_register()); 724 __ mov(StackOperand(variable), result_register());
725 } else if (mode == Variable::CONST || mode == Variable::LET) { 725 } else if (mode == CONST || mode == LET) {
726 Comment cmnt(masm_, "[ Declaration"); 726 Comment cmnt(masm_, "[ Declaration");
727 __ mov(StackOperand(variable), 727 __ mov(StackOperand(variable),
728 Immediate(isolate()->factory()->the_hole_value())); 728 Immediate(isolate()->factory()->the_hole_value()));
729 } 729 }
730 break; 730 break;
731 731
732 case Variable::CONTEXT: 732 case Variable::CONTEXT:
733 // The variable in the decl always resides in the current function 733 // The variable in the decl always resides in the current function
734 // context. 734 // context.
735 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); 735 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
(...skipping 11 matching lines...) Expand all
747 __ mov(ContextOperand(esi, variable->index()), result_register()); 747 __ mov(ContextOperand(esi, variable->index()), result_register());
748 // We know that we have written a function, which is not a smi. 748 // We know that we have written a function, which is not a smi.
749 __ RecordWriteContextSlot(esi, 749 __ RecordWriteContextSlot(esi,
750 Context::SlotOffset(variable->index()), 750 Context::SlotOffset(variable->index()),
751 result_register(), 751 result_register(),
752 ecx, 752 ecx,
753 kDontSaveFPRegs, 753 kDontSaveFPRegs,
754 EMIT_REMEMBERED_SET, 754 EMIT_REMEMBERED_SET,
755 OMIT_SMI_CHECK); 755 OMIT_SMI_CHECK);
756 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 756 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
757 } else if (mode == Variable::CONST || mode == Variable::LET) { 757 } else if (mode == CONST || mode == LET) {
758 Comment cmnt(masm_, "[ Declaration"); 758 Comment cmnt(masm_, "[ Declaration");
759 __ mov(ContextOperand(esi, variable->index()), 759 __ mov(ContextOperand(esi, variable->index()),
760 Immediate(isolate()->factory()->the_hole_value())); 760 Immediate(isolate()->factory()->the_hole_value()));
761 // No write barrier since the hole value is in old space. 761 // No write barrier since the hole value is in old space.
762 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 762 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
763 } 763 }
764 break; 764 break;
765 765
766 case Variable::LOOKUP: { 766 case Variable::LOOKUP: {
767 Comment cmnt(masm_, "[ Declaration"); 767 Comment cmnt(masm_, "[ Declaration");
768 __ push(esi); 768 __ push(esi);
769 __ push(Immediate(variable->name())); 769 __ push(Immediate(variable->name()));
770 // Declaration nodes are always introduced in one of three modes. 770 // Declaration nodes are always introduced in one of three modes.
771 ASSERT(mode == Variable::VAR || 771 ASSERT(mode == VAR || mode == CONST || mode == LET);
772 mode == Variable::CONST || 772 PropertyAttributes attr = (mode == CONST) ? READ_ONLY : NONE;
773 mode == Variable::LET);
774 PropertyAttributes attr = (mode == Variable::CONST) ? READ_ONLY : NONE;
775 __ push(Immediate(Smi::FromInt(attr))); 773 __ push(Immediate(Smi::FromInt(attr)));
776 // Push initial value, if any. 774 // Push initial value, if any.
777 // Note: For variables we must not push an initial value (such as 775 // Note: For variables we must not push an initial value (such as
778 // 'undefined') because we may have a (legal) redeclaration and we 776 // 'undefined') because we may have a (legal) redeclaration and we
779 // must not destroy the current value. 777 // must not destroy the current value.
780 increment_stack_height(3); 778 increment_stack_height(3);
781 if (function != NULL) { 779 if (function != NULL) {
782 VisitForStackValue(function); 780 VisitForStackValue(function);
783 } else if (mode == Variable::CONST || mode == Variable::LET) { 781 } else if (mode == CONST || mode == LET) {
784 __ push(Immediate(isolate()->factory()->the_hole_value())); 782 __ push(Immediate(isolate()->factory()->the_hole_value()));
785 increment_stack_height(); 783 increment_stack_height();
786 } else { 784 } else {
787 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. 785 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value.
788 increment_stack_height(); 786 increment_stack_height();
789 } 787 }
790 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 788 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
791 decrement_stack_height(4); 789 decrement_stack_height(4);
792 break; 790 break;
793 } 791 }
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 1192
1195 void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var, 1193 void FullCodeGenerator::EmitDynamicLookupFastCase(Variable* var,
1196 TypeofState typeof_state, 1194 TypeofState typeof_state,
1197 Label* slow, 1195 Label* slow,
1198 Label* done) { 1196 Label* done) {
1199 // Generate fast-case code for variables that might be shadowed by 1197 // Generate fast-case code for variables that might be shadowed by
1200 // eval-introduced variables. Eval is used a lot without 1198 // eval-introduced variables. Eval is used a lot without
1201 // introducing variables. In those cases, we do not want to 1199 // introducing variables. In those cases, we do not want to
1202 // perform a runtime call for all variables in the scope 1200 // perform a runtime call for all variables in the scope
1203 // containing the eval. 1201 // containing the eval.
1204 if (var->mode() == Variable::DYNAMIC_GLOBAL) { 1202 if (var->mode() == DYNAMIC_GLOBAL) {
1205 EmitLoadGlobalCheckExtensions(var, typeof_state, slow); 1203 EmitLoadGlobalCheckExtensions(var, typeof_state, slow);
1206 __ jmp(done); 1204 __ jmp(done);
1207 } else if (var->mode() == Variable::DYNAMIC_LOCAL) { 1205 } else if (var->mode() == DYNAMIC_LOCAL) {
1208 Variable* local = var->local_if_not_shadowed(); 1206 Variable* local = var->local_if_not_shadowed();
1209 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow)); 1207 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow));
1210 if (local->mode() == Variable::CONST || 1208 if (local->mode() == CONST ||
1211 local->mode() == Variable::LET) { 1209 local->mode() == LET) {
1212 __ cmp(eax, isolate()->factory()->the_hole_value()); 1210 __ cmp(eax, isolate()->factory()->the_hole_value());
1213 __ j(not_equal, done); 1211 __ j(not_equal, done);
1214 if (local->mode() == Variable::CONST) { 1212 if (local->mode() == CONST) {
1215 __ mov(eax, isolate()->factory()->undefined_value()); 1213 __ mov(eax, isolate()->factory()->undefined_value());
1216 } else { // Variable::LET 1214 } else { // LET
1217 __ push(Immediate(var->name())); 1215 __ push(Immediate(var->name()));
1218 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1216 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1219 } 1217 }
1220 } 1218 }
1221 __ jmp(done); 1219 __ jmp(done);
1222 } 1220 }
1223 } 1221 }
1224 1222
1225 1223
1226 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1224 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
(...skipping 15 matching lines...) Expand all
1242 context()->Plug(eax); 1240 context()->Plug(eax);
1243 break; 1241 break;
1244 } 1242 }
1245 1243
1246 case Variable::PARAMETER: 1244 case Variable::PARAMETER:
1247 case Variable::LOCAL: 1245 case Variable::LOCAL:
1248 case Variable::CONTEXT: { 1246 case Variable::CONTEXT: {
1249 Comment cmnt(masm_, var->IsContextSlot() 1247 Comment cmnt(masm_, var->IsContextSlot()
1250 ? "Context variable" 1248 ? "Context variable"
1251 : "Stack variable"); 1249 : "Stack variable");
1252 if (var->mode() != Variable::LET && var->mode() != Variable::CONST) { 1250 if (var->mode() != LET && var->mode() != CONST) {
1253 context()->Plug(var); 1251 context()->Plug(var);
1254 } else { 1252 } else {
1255 // Let and const need a read barrier. 1253 // Let and const need a read barrier.
1256 Label done; 1254 Label done;
1257 GetVar(eax, var); 1255 GetVar(eax, var);
1258 __ cmp(eax, isolate()->factory()->the_hole_value()); 1256 __ cmp(eax, isolate()->factory()->the_hole_value());
1259 __ j(not_equal, &done, Label::kNear); 1257 __ j(not_equal, &done, Label::kNear);
1260 if (var->mode() == Variable::LET) { 1258 if (var->mode() == LET) {
1261 __ push(Immediate(var->name())); 1259 __ push(Immediate(var->name()));
1262 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1260 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1263 } else { // Variable::CONST 1261 } else { // CONST
1264 __ mov(eax, isolate()->factory()->undefined_value()); 1262 __ mov(eax, isolate()->factory()->undefined_value());
1265 } 1263 }
1266 __ bind(&done); 1264 __ bind(&done);
1267 context()->Plug(eax); 1265 context()->Plug(eax);
1268 } 1266 }
1269 break; 1267 break;
1270 } 1268 }
1271 1269
1272 case Variable::LOOKUP: { 1270 case Variable::LOOKUP: {
1273 Label done, slow; 1271 Label done, slow;
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 // scope. However, unlike var initializers, const initializers are 1857 // scope. However, unlike var initializers, const initializers are
1860 // able to drill a hole to that function context, even from inside a 1858 // able to drill a hole to that function context, even from inside a
1861 // 'with' context. We thus bypass the normal static scope lookup for 1859 // 'with' context. We thus bypass the normal static scope lookup for
1862 // var->IsContextSlot(). 1860 // var->IsContextSlot().
1863 __ push(eax); 1861 __ push(eax);
1864 __ push(esi); 1862 __ push(esi);
1865 __ push(Immediate(var->name())); 1863 __ push(Immediate(var->name()));
1866 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 1864 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1867 } 1865 }
1868 1866
1869 } else if (var->mode() == Variable::LET && op != Token::INIT_LET) { 1867 } else if (var->mode() == LET && op != Token::INIT_LET) {
1870 // Non-initializing assignment to let variable needs a write barrier. 1868 // Non-initializing assignment to let variable needs a write barrier.
1871 if (var->IsLookupSlot()) { 1869 if (var->IsLookupSlot()) {
1872 __ push(eax); // Value. 1870 __ push(eax); // Value.
1873 __ push(esi); // Context. 1871 __ push(esi); // Context.
1874 __ push(Immediate(var->name())); 1872 __ push(Immediate(var->name()));
1875 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 1873 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
1876 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1874 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1877 } else { 1875 } else {
1878 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 1876 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
1879 Label assign; 1877 Label assign;
1880 MemOperand location = VarOperand(var, ecx); 1878 MemOperand location = VarOperand(var, ecx);
1881 __ mov(edx, location); 1879 __ mov(edx, location);
1882 __ cmp(edx, isolate()->factory()->the_hole_value()); 1880 __ cmp(edx, isolate()->factory()->the_hole_value());
1883 __ j(not_equal, &assign, Label::kNear); 1881 __ j(not_equal, &assign, Label::kNear);
1884 __ push(Immediate(var->name())); 1882 __ push(Immediate(var->name()));
1885 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1883 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1886 __ bind(&assign); 1884 __ bind(&assign);
1887 __ mov(location, eax); 1885 __ mov(location, eax);
1888 if (var->IsContextSlot()) { 1886 if (var->IsContextSlot()) {
1889 __ mov(edx, eax); 1887 __ mov(edx, eax);
1890 int offset = Context::SlotOffset(var->index()); 1888 int offset = Context::SlotOffset(var->index());
1891 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 1889 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs);
1892 } 1890 }
1893 } 1891 }
1894 1892
1895 } else if (var->mode() != Variable::CONST) { 1893 } else if (var->mode() != CONST) {
1896 // Assignment to var or initializing assignment to let. 1894 // Assignment to var or initializing assignment to let.
1897 if (var->IsStackAllocated() || var->IsContextSlot()) { 1895 if (var->IsStackAllocated() || var->IsContextSlot()) {
1898 MemOperand location = VarOperand(var, ecx); 1896 MemOperand location = VarOperand(var, ecx);
1899 if (FLAG_debug_code && op == Token::INIT_LET) { 1897 if (FLAG_debug_code && op == Token::INIT_LET) {
1900 // Check for an uninitialized let binding. 1898 // Check for an uninitialized let binding.
1901 __ mov(edx, location); 1899 __ mov(edx, location);
1902 __ cmp(edx, isolate()->factory()->the_hole_value()); 1900 __ cmp(edx, isolate()->factory()->the_hole_value());
1903 __ Check(equal, "Let binding re-initialization."); 1901 __ Check(equal, "Let binding re-initialization.");
1904 } 1902 }
1905 // Perform the assignment. 1903 // Perform the assignment.
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
2184 for (int i = 0; i < arg_count; i++) { 2182 for (int i = 0; i < arg_count; i++) {
2185 VisitForStackValue(args->at(i)); 2183 VisitForStackValue(args->at(i));
2186 } 2184 }
2187 2185
2188 // If we know that eval can only be shadowed by eval-introduced 2186 // If we know that eval can only be shadowed by eval-introduced
2189 // variables we attempt to load the global eval function directly in 2187 // variables we attempt to load the global eval function directly in
2190 // generated code. If we succeed, there is no need to perform a 2188 // generated code. If we succeed, there is no need to perform a
2191 // context lookup in the runtime system. 2189 // context lookup in the runtime system.
2192 Label done; 2190 Label done;
2193 Variable* var = proxy->var(); 2191 Variable* var = proxy->var();
2194 if (!var->IsUnallocated() && var->mode() == Variable::DYNAMIC_GLOBAL) { 2192 if (!var->IsUnallocated() && var->mode() == DYNAMIC_GLOBAL) {
2195 Label slow; 2193 Label slow;
2196 EmitLoadGlobalCheckExtensions(var, NOT_INSIDE_TYPEOF, &slow); 2194 EmitLoadGlobalCheckExtensions(var, NOT_INSIDE_TYPEOF, &slow);
2197 // Push the function and resolve eval. 2195 // Push the function and resolve eval.
2198 __ push(eax); 2196 __ push(eax);
2199 EmitResolvePossiblyDirectEval(SKIP_CONTEXT_LOOKUP, arg_count); 2197 EmitResolvePossiblyDirectEval(SKIP_CONTEXT_LOOKUP, arg_count);
2200 __ jmp(&done); 2198 __ jmp(&done);
2201 __ bind(&slow); 2199 __ bind(&slow);
2202 } 2200 }
2203 2201
2204 // Push a copy of the function (found below the arguments) and 2202 // Push a copy of the function (found below the arguments) and
(...skipping 2142 matching lines...) Expand 10 before | Expand all | Expand 10 after
4347 *context_length = 0; 4345 *context_length = 0;
4348 return previous_; 4346 return previous_;
4349 } 4347 }
4350 4348
4351 4349
4352 #undef __ 4350 #undef __
4353 4351
4354 } } // namespace v8::internal 4352 } } // namespace v8::internal
4355 4353
4356 #endif // V8_TARGET_ARCH_IA32 4354 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/objects.h » ('j') | src/parser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698