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

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

Issue 7860035: Merge bleeding edge up to 9192 into the GC branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
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/full-codegen.h ('k') | src/globals.h » ('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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 // Return is breakable if the expression is. 89 // Return is breakable if the expression is.
90 Visit(stmt->expression()); 90 Visit(stmt->expression());
91 } 91 }
92 92
93 93
94 void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) { 94 void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) {
95 Visit(stmt->expression()); 95 Visit(stmt->expression());
96 } 96 }
97 97
98 98
99 void BreakableStatementChecker::VisitExitContextStatement(
100 ExitContextStatement* stmt) {
101 }
102
103
104 void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) { 99 void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) {
105 // Switch statements breakable if the tag expression is. 100 // Switch statements breakable if the tag expression is.
106 Visit(stmt->tag()); 101 Visit(stmt->tag());
107 } 102 }
108 103
109 104
110 void BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) { 105 void BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
111 // Mark do while as breakable to avoid adding a break slot in front of it. 106 // Mark do while as breakable to avoid adding a break slot in front of it.
112 is_breakable_ = true; 107 is_breakable_ = true;
113 } 108 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 } 178 }
184 179
185 180
186 void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) { 181 void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) {
187 } 182 }
188 183
189 184
190 void BreakableStatementChecker::VisitAssignment(Assignment* expr) { 185 void BreakableStatementChecker::VisitAssignment(Assignment* expr) {
191 // If assigning to a property (including a global property) the assignment is 186 // If assigning to a property (including a global property) the assignment is
192 // breakable. 187 // breakable.
193 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 188 VariableProxy* proxy = expr->target()->AsVariableProxy();
194 Property* prop = expr->target()->AsProperty(); 189 Property* prop = expr->target()->AsProperty();
195 if (prop != NULL || (var != NULL && var->is_global())) { 190 if (prop != NULL || (proxy != NULL && proxy->var()->IsUnallocated())) {
196 is_breakable_ = true; 191 is_breakable_ = true;
197 return; 192 return;
198 } 193 }
199 194
200 // Otherwise the assignment is breakable if the assigned value is. 195 // Otherwise the assignment is breakable if the assigned value is.
201 Visit(expr->value()); 196 Visit(expr->value());
202 } 197 }
203 198
204 199
205 void BreakableStatementChecker::VisitThrow(Throw* expr) { 200 void BreakableStatementChecker::VisitThrow(Throw* expr) {
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 383
389 384
390 void FullCodeGenerator::RecordStackCheck(int ast_id) { 385 void FullCodeGenerator::RecordStackCheck(int ast_id) {
391 // The pc offset does not need to be encoded and packed together with a 386 // The pc offset does not need to be encoded and packed together with a
392 // state. 387 // state.
393 BailoutEntry entry = { ast_id, masm_->pc_offset() }; 388 BailoutEntry entry = { ast_id, masm_->pc_offset() };
394 stack_checks_.Add(entry); 389 stack_checks_.Add(entry);
395 } 390 }
396 391
397 392
398 int FullCodeGenerator::SlotOffset(Slot* slot) {
399 ASSERT(slot != NULL);
400 // Offset is negative because higher indexes are at lower addresses.
401 int offset = -slot->index() * kPointerSize;
402 // Adjust by a (parameter or local) base offset.
403 switch (slot->type()) {
404 case Slot::PARAMETER:
405 offset += (info_->scope()->num_parameters() + 1) * kPointerSize;
406 break;
407 case Slot::LOCAL:
408 offset += JavaScriptFrameConstants::kLocal0Offset;
409 break;
410 case Slot::CONTEXT:
411 case Slot::LOOKUP:
412 UNREACHABLE();
413 }
414 return offset;
415 }
416
417
418 bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) { 393 bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) {
419 // Inline smi case inside loops, but not division and modulo which 394 // Inline smi case inside loops, but not division and modulo which
420 // are too complicated and take up too much space. 395 // are too complicated and take up too much space.
421 if (op == Token::DIV ||op == Token::MOD) return false; 396 if (op == Token::DIV ||op == Token::MOD) return false;
422 if (FLAG_always_inline_smi_code) return true; 397 if (FLAG_always_inline_smi_code) return true;
423 return loop_depth_ > 0; 398 return loop_depth_ > 0;
424 } 399 }
425 400
426 401
427 void FullCodeGenerator::EffectContext::Plug(Register reg) const { 402 void FullCodeGenerator::EffectContext::Plug(Register reg) const {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 DoTest(context->condition(), 497 DoTest(context->condition(),
523 context->true_label(), 498 context->true_label(),
524 context->false_label(), 499 context->false_label(),
525 context->fall_through()); 500 context->fall_through());
526 } 501 }
527 502
528 503
529 void FullCodeGenerator::VisitDeclarations( 504 void FullCodeGenerator::VisitDeclarations(
530 ZoneList<Declaration*>* declarations) { 505 ZoneList<Declaration*>* declarations) {
531 int length = declarations->length(); 506 int length = declarations->length();
532 int globals = 0; 507 int global_count = 0;
533 for (int i = 0; i < length; i++) { 508 for (int i = 0; i < length; i++) {
534 Declaration* decl = declarations->at(i); 509 Declaration* decl = declarations->at(i);
535 Variable* var = decl->proxy()->var(); 510 EmitDeclaration(decl->proxy(), decl->mode(), decl->fun(), &global_count);
536 Slot* slot = var->AsSlot();
537
538 // If it was not possible to allocate the variable at compile
539 // time, we need to "declare" it at runtime to make sure it
540 // actually exists in the local context.
541 if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) {
542 VisitDeclaration(decl);
543 } else {
544 // Count global variables and functions for later processing
545 globals++;
546 }
547 } 511 }
548 512
549 // Compute array of global variable and function declarations. 513 // Batch declare global functions and variables.
550 // Do nothing in case of no declared global functions or variables. 514 if (global_count > 0) {
551 if (globals > 0) {
552 Handle<FixedArray> array = 515 Handle<FixedArray> array =
553 isolate()->factory()->NewFixedArray(2 * globals, TENURED); 516 isolate()->factory()->NewFixedArray(2 * global_count, TENURED);
554 for (int j = 0, i = 0; i < length; i++) { 517 for (int j = 0, i = 0; i < length; i++) {
555 Declaration* decl = declarations->at(i); 518 Declaration* decl = declarations->at(i);
556 Variable* var = decl->proxy()->var(); 519 Variable* var = decl->proxy()->var();
557 Slot* slot = var->AsSlot();
558 520
559 if ((slot == NULL || slot->type() != Slot::LOOKUP) && var->is_global()) { 521 if (var->IsUnallocated()) {
560 array->set(j++, *(var->name())); 522 array->set(j++, *(var->name()));
561 if (decl->fun() == NULL) { 523 if (decl->fun() == NULL) {
562 if (var->mode() == Variable::CONST) { 524 if (var->mode() == Variable::CONST) {
563 // In case this is const property use the hole. 525 // In case this is const property use the hole.
564 array->set_the_hole(j++); 526 array->set_the_hole(j++);
565 } else { 527 } else {
566 array->set_undefined(j++); 528 array->set_undefined(j++);
567 } 529 }
568 } else { 530 } else {
569 Handle<SharedFunctionInfo> function = 531 Handle<SharedFunctionInfo> function =
570 Compiler::BuildFunctionInfo(decl->fun(), script()); 532 Compiler::BuildFunctionInfo(decl->fun(), script());
571 // Check for stack-overflow exception. 533 // Check for stack-overflow exception.
572 if (function.is_null()) { 534 if (function.is_null()) {
573 SetStackOverflow(); 535 SetStackOverflow();
574 return; 536 return;
575 } 537 }
576 array->set(j++, *function); 538 array->set(j++, *function);
577 } 539 }
578 } 540 }
579 } 541 }
580 // Invoke the platform-dependent code generator to do the actual 542 // Invoke the platform-dependent code generator to do the actual
581 // declaration the global variables and functions. 543 // declaration the global functions and variables.
582 DeclareGlobals(array); 544 DeclareGlobals(array);
583 } 545 }
584 } 546 }
585 547
586 548
549 int FullCodeGenerator::DeclareGlobalsFlags() {
550 int flags = 0;
551 if (is_eval()) flags |= kDeclareGlobalsEvalFlag;
552 if (is_strict_mode()) flags |= kDeclareGlobalsStrictModeFlag;
553 if (is_native()) flags |= kDeclareGlobalsNativeFlag;
554 return flags;
555 }
556
557
587 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { 558 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
588 CodeGenerator::RecordPositions(masm_, fun->start_position()); 559 CodeGenerator::RecordPositions(masm_, fun->start_position());
589 } 560 }
590 561
591 562
592 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { 563 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
593 CodeGenerator::RecordPositions(masm_, fun->end_position() - 1); 564 CodeGenerator::RecordPositions(masm_, fun->end_position() - 1);
594 } 565 }
595 566
596 567
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 PrepareForBailout(expr, state); 806 PrepareForBailout(expr, state);
836 // Forwarding bailouts to children is a one shot operation. It should have 807 // Forwarding bailouts to children is a one shot operation. It should have
837 // been processed at this point. 808 // been processed at this point.
838 ASSERT(forward_bailout_pending_ == NULL); 809 ASSERT(forward_bailout_pending_ == NULL);
839 } 810 }
840 } 811 }
841 812
842 813
843 void FullCodeGenerator::VisitBlock(Block* stmt) { 814 void FullCodeGenerator::VisitBlock(Block* stmt) {
844 Comment cmnt(masm_, "[ Block"); 815 Comment cmnt(masm_, "[ Block");
845 Breakable nested_statement(this, stmt); 816 NestedBlock nested_block(this, stmt);
846 SetStatementPosition(stmt); 817 SetStatementPosition(stmt);
847 818
848 Scope* saved_scope = scope(); 819 Scope* saved_scope = scope();
820 // Push a block context when entering a block with block scoped variables.
849 if (stmt->block_scope() != NULL) { 821 if (stmt->block_scope() != NULL) {
850 { Comment cmnt(masm_, "[ Extend block context"); 822 { Comment cmnt(masm_, "[ Extend block context");
851 scope_ = stmt->block_scope(); 823 scope_ = stmt->block_scope();
852 __ Push(scope_->GetSerializedScopeInfo()); 824 __ Push(scope_->GetSerializedScopeInfo());
853 PushFunctionArgumentForContextAllocation(); 825 PushFunctionArgumentForContextAllocation();
854 __ CallRuntime(Runtime::kPushBlockContext, 2); 826 __ CallRuntime(Runtime::kPushBlockContext, 2);
855 StoreToFrameField(StandardFrameConstants::kContextOffset, 827 StoreToFrameField(StandardFrameConstants::kContextOffset,
856 context_register()); 828 context_register());
857 } 829 }
858 { Comment cmnt(masm_, "[ Declarations"); 830 { Comment cmnt(masm_, "[ Declarations");
859 VisitDeclarations(scope_->declarations()); 831 VisitDeclarations(scope_->declarations());
860 } 832 }
861 } 833 }
862 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 834 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
863 VisitStatements(stmt->statements()); 835 VisitStatements(stmt->statements());
864 scope_ = saved_scope; 836 scope_ = saved_scope;
865 __ bind(nested_statement.break_label()); 837 __ bind(nested_block.break_label());
866 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 838 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
839
840 // Pop block context if necessary.
841 if (stmt->block_scope() != NULL) {
842 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
843 // Update local stack frame context field.
844 StoreToFrameField(StandardFrameConstants::kContextOffset,
845 context_register());
846 }
867 } 847 }
868 848
869 849
870 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 850 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
871 Comment cmnt(masm_, "[ ExpressionStatement"); 851 Comment cmnt(masm_, "[ ExpressionStatement");
872 SetStatementPosition(stmt); 852 SetStatementPosition(stmt);
873 VisitForEffect(stmt->expression()); 853 VisitForEffect(stmt->expression());
874 } 854 }
875 855
876 856
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 Visit(stmt->statement()); 977 Visit(stmt->statement());
998 } 978 }
999 979
1000 // Pop context. 980 // Pop context.
1001 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 981 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1002 // Update local stack frame context field. 982 // Update local stack frame context field.
1003 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 983 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1004 } 984 }
1005 985
1006 986
1007 void FullCodeGenerator::VisitExitContextStatement(ExitContextStatement* stmt) {
1008 Comment cmnt(masm_, "[ ExitContextStatement");
1009 SetStatementPosition(stmt);
1010
1011 // Pop context.
1012 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1013 // Update local stack frame context field.
1014 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1015 }
1016
1017
1018 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 987 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
1019 Comment cmnt(masm_, "[ DoWhileStatement"); 988 Comment cmnt(masm_, "[ DoWhileStatement");
1020 SetStatementPosition(stmt); 989 SetStatementPosition(stmt);
1021 Label body, stack_check; 990 Label body, stack_check;
1022 991
1023 Iteration loop_statement(this, stmt); 992 Iteration loop_statement(this, stmt);
1024 increment_loop_depth(); 993 increment_loop_depth();
1025 994
1026 __ bind(&body); 995 __ bind(&body);
1027 Visit(stmt->body()); 996 Visit(stmt->body());
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 StoreToFrameField(StandardFrameConstants::kContextOffset, 1124 StoreToFrameField(StandardFrameConstants::kContextOffset,
1156 context_register()); 1125 context_register());
1157 } 1126 }
1158 1127
1159 Scope* saved_scope = scope(); 1128 Scope* saved_scope = scope();
1160 scope_ = stmt->scope(); 1129 scope_ = stmt->scope();
1161 ASSERT(scope_->declarations()->is_empty()); 1130 ASSERT(scope_->declarations()->is_empty());
1162 { WithOrCatch body(this); 1131 { WithOrCatch body(this);
1163 Visit(stmt->catch_block()); 1132 Visit(stmt->catch_block());
1164 } 1133 }
1134 // Restore the context.
1135 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1136 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1165 scope_ = saved_scope; 1137 scope_ = saved_scope;
1166 __ jmp(&done); 1138 __ jmp(&done);
1167 1139
1168 // Try block code. Sets up the exception handler chain. 1140 // Try block code. Sets up the exception handler chain.
1169 __ bind(&try_handler_setup); 1141 __ bind(&try_handler_setup);
1170 { 1142 {
1171 const int delta = StackHandlerConstants::kSize / kPointerSize; 1143 const int delta = StackHandlerConstants::kSize / kPointerSize;
1172 TryCatch try_block(this); 1144 TryCatch try_block(this);
1173 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); 1145 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER);
1174 increment_stack_height(delta); 1146 increment_stack_height(delta);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 Comment cmnt(masm_, "[ Throw"); 1301 Comment cmnt(masm_, "[ Throw");
1330 // Throw has no effect on the stack height or the current expression context. 1302 // Throw has no effect on the stack height or the current expression context.
1331 // Usually the expression context is null, because throw is a statement. 1303 // Usually the expression context is null, because throw is a statement.
1332 VisitForStackValue(expr->exception()); 1304 VisitForStackValue(expr->exception());
1333 __ CallRuntime(Runtime::kThrow, 1); 1305 __ CallRuntime(Runtime::kThrow, 1);
1334 decrement_stack_height(); 1306 decrement_stack_height();
1335 // Never returns here. 1307 // Never returns here.
1336 } 1308 }
1337 1309
1338 1310
1339 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
1340 int* stack_depth,
1341 int* context_length) {
1342 // The macros used here must preserve the result register.
1343 __ Drop(*stack_depth);
1344 __ PopTryHandler();
1345 *stack_depth = 0;
1346
1347 Register context = FullCodeGenerator::context_register();
1348 while (*context_length > 0) {
1349 codegen_->LoadContextField(context, Context::PREVIOUS_INDEX);
1350 --(*context_length);
1351 }
1352
1353 __ Call(finally_entry_);
1354 return previous_;
1355 }
1356
1357
1358 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit( 1311 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit(
1359 int* stack_depth, 1312 int* stack_depth,
1360 int* context_length) { 1313 int* context_length) {
1361 // The macros used here must preserve the result register. 1314 // The macros used here must preserve the result register.
1362 __ Drop(*stack_depth); 1315 __ Drop(*stack_depth);
1363 __ PopTryHandler(); 1316 __ PopTryHandler();
1364 *stack_depth = 0; 1317 *stack_depth = 0;
1365 return previous_; 1318 return previous_;
1366 } 1319 }
1367 1320
(...skipping 15 matching lines...) Expand all
1383 } 1336 }
1384 1337
1385 return false; 1338 return false;
1386 } 1339 }
1387 1340
1388 1341
1389 #undef __ 1342 #undef __
1390 1343
1391 1344
1392 } } // namespace v8::internal 1345 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/globals.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698