diff options
| author | Ben Murdoch <benm@google.com> | 2011-11-30 16:03:39 +0000 |
|---|---|---|
| committer | Ben Murdoch <benm@google.com> | 2011-12-02 17:28:02 +0000 |
| commit | 69a99ed0b2b2ef69d393c371b03db3a98aaf880e (patch) | |
| tree | 6438154d0f3ab526b9206f8860fa4db5cf073c11 /src/full-codegen.cc | |
| parent | 3fb3ca8c7ca439d408449a395897395c0faae8d1 (diff) | |
| download | android_external_v8-69a99ed0b2b2ef69d393c371b03db3a98aaf880e.tar.gz android_external_v8-69a99ed0b2b2ef69d393c371b03db3a98aaf880e.tar.bz2 android_external_v8-69a99ed0b2b2ef69d393c371b03db3a98aaf880e.zip | |
Upgrade to V8 3.5
Merge V8 3.5.10.24
Simple merge required updates to makefiles only.
Bug: 5688872
Change-Id: I0acdb9a1a53919d84e9a7525308e8371739d2f06
Diffstat (limited to 'src/full-codegen.cc')
| -rw-r--r-- | src/full-codegen.cc | 141 |
1 files changed, 95 insertions, 46 deletions
diff --git a/src/full-codegen.cc b/src/full-codegen.cc index 8c2f0d17..ca2026bb 100644 --- a/src/full-codegen.cc +++ b/src/full-codegen.cc @@ -35,6 +35,7 @@ #include "macro-assembler.h" #include "prettyprinter.h" #include "scopes.h" +#include "scopeinfo.h" #include "stub-cache.h" namespace v8 { @@ -90,8 +91,7 @@ void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) { } -void BreakableStatementChecker::VisitEnterWithContextStatement( - EnterWithContextStatement* stmt) { +void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) { Visit(stmt->expression()); } @@ -317,7 +317,6 @@ unsigned FullCodeGenerator::EmitStackCheckTable() { // field, and then a sequence of entries. Each entry is a pair of AST id // and code-relative pc offset. masm()->Align(kIntSize); - masm()->RecordComment("[ Stack check table"); unsigned offset = masm()->pc_offset(); unsigned length = stack_checks_.length(); __ dd(length); @@ -325,7 +324,6 @@ unsigned FullCodeGenerator::EmitStackCheckTable() { __ dd(stack_checks_[i].id); __ dd(stack_checks_[i].pc_and_state); } - masm()->RecordComment("]"); return offset; } @@ -437,6 +435,7 @@ void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { void FullCodeGenerator::StackValueContext::Plug(Register reg) const { __ push(reg); + codegen()->increment_stack_height(); } @@ -450,11 +449,13 @@ void FullCodeGenerator::TestContext::Plug(Register reg) const { void FullCodeGenerator::EffectContext::PlugTOS() const { __ Drop(1); + codegen()->decrement_stack_height(); } void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { __ pop(result_register()); + codegen()->decrement_stack_height(); } @@ -465,6 +466,7 @@ void FullCodeGenerator::StackValueContext::PlugTOS() const { void FullCodeGenerator::TestContext::PlugTOS() const { // For simplicity we always test the accumulator register. __ pop(result_register()); + codegen()->decrement_stack_height(); codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); codegen()->DoTest(this); } @@ -843,9 +845,24 @@ void FullCodeGenerator::VisitBlock(Block* stmt) { Breakable nested_statement(this, stmt); SetStatementPosition(stmt); + Scope* saved_scope = scope(); + if (stmt->block_scope() != NULL) { + { Comment cmnt(masm_, "[ Extend block context"); + scope_ = stmt->block_scope(); + __ Push(scope_->GetSerializedScopeInfo()); + PushFunctionArgumentForContextAllocation(); + __ CallRuntime(Runtime::kPushBlockContext, 2); + StoreToFrameField(StandardFrameConstants::kContextOffset, + context_register()); + } + { Comment cmnt(masm_, "[ Declarations"); + VisitDeclarations(scope_->declarations()); + } + } PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); VisitStatements(stmt->statements()); - __ bind(nested_statement.break_target()); + scope_ = saved_scope; + __ bind(nested_statement.break_label()); PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); } @@ -896,19 +913,26 @@ void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { SetStatementPosition(stmt); NestedStatement* current = nesting_stack_; int stack_depth = 0; + int context_length = 0; // When continuing, we clobber the unpredictable value in the accumulator // with one that's safe for GC. If we hit an exit from the try block of // try...finally on our way out, we will unconditionally preserve the // accumulator on the stack. ClearAccumulator(); while (!current->IsContinueTarget(stmt->target())) { - stack_depth = current->Exit(stack_depth); - current = current->outer(); + current = current->Exit(&stack_depth, &context_length); } __ Drop(stack_depth); + if (context_length > 0) { + while (context_length > 0) { + LoadContextField(context_register(), Context::PREVIOUS_INDEX); + --context_length; + } + StoreToFrameField(StandardFrameConstants::kContextOffset, + context_register()); + } - Iteration* loop = current->AsIteration(); - __ jmp(loop->continue_target()); + __ jmp(current->AsIteration()->continue_label()); } @@ -917,19 +941,26 @@ void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { SetStatementPosition(stmt); NestedStatement* current = nesting_stack_; int stack_depth = 0; + int context_length = 0; // When breaking, we clobber the unpredictable value in the accumulator // with one that's safe for GC. If we hit an exit from the try block of // try...finally on our way out, we will unconditionally preserve the // accumulator on the stack. ClearAccumulator(); while (!current->IsBreakTarget(stmt->target())) { - stack_depth = current->Exit(stack_depth); - current = current->outer(); + current = current->Exit(&stack_depth, &context_length); } __ Drop(stack_depth); + if (context_length > 0) { + while (context_length > 0) { + LoadContextField(context_register(), Context::PREVIOUS_INDEX); + --context_length; + } + StoreToFrameField(StandardFrameConstants::kContextOffset, + context_register()); + } - Breakable* target = current->AsBreakable(); - __ jmp(target->break_target()); + __ jmp(current->AsBreakable()->break_label()); } @@ -942,9 +973,9 @@ void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { // Exit all nested statements. NestedStatement* current = nesting_stack_; int stack_depth = 0; + int context_length = 0; while (current != NULL) { - stack_depth = current->Exit(stack_depth); - current = current->outer(); + current = current->Exit(&stack_depth, &context_length); } __ Drop(stack_depth); @@ -952,14 +983,23 @@ void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { } -void FullCodeGenerator::VisitEnterWithContextStatement( - EnterWithContextStatement* stmt) { - Comment cmnt(masm_, "[ EnterWithContextStatement"); +void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { + Comment cmnt(masm_, "[ WithStatement"); SetStatementPosition(stmt); VisitForStackValue(stmt->expression()); PushFunctionArgumentForContextAllocation(); __ CallRuntime(Runtime::kPushWithContext, 2); + decrement_stack_height(); + StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); + + { WithOrCatch body(this); + Visit(stmt->statement()); + } + + // Pop context. + LoadContextField(context_register(), Context::PREVIOUS_INDEX); + // Update local stack frame context field. StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); } @@ -988,12 +1028,12 @@ void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { // Record the position of the do while condition and make sure it is // possible to break on the condition. - __ bind(loop_statement.continue_target()); + __ bind(loop_statement.continue_label()); PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); SetExpressionPosition(stmt->cond(), stmt->condition_position()); VisitForControl(stmt->cond(), &stack_check, - loop_statement.break_target(), + loop_statement.break_label(), &stack_check); // Check stack before looping. @@ -1003,7 +1043,7 @@ void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { __ jmp(&body); PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); - __ bind(loop_statement.break_target()); + __ bind(loop_statement.break_label()); decrement_loop_depth(); } @@ -1024,7 +1064,7 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { // Emit the statement position here as this is where the while // statement code starts. - __ bind(loop_statement.continue_target()); + __ bind(loop_statement.continue_label()); SetStatementPosition(stmt); // Check stack before looping. @@ -1033,11 +1073,11 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { __ bind(&test); VisitForControl(stmt->cond(), &body, - loop_statement.break_target(), - loop_statement.break_target()); + loop_statement.break_label(), + loop_statement.break_label()); PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); - __ bind(loop_statement.break_target()); + __ bind(loop_statement.break_label()); decrement_loop_depth(); } @@ -1060,7 +1100,7 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { Visit(stmt->body()); PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); - __ bind(loop_statement.continue_target()); + __ bind(loop_statement.continue_label()); SetStatementPosition(stmt); if (stmt->next() != NULL) { Visit(stmt->next()); @@ -1077,14 +1117,14 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { if (stmt->cond() != NULL) { VisitForControl(stmt->cond(), &body, - loop_statement.break_target(), - loop_statement.break_target()); + loop_statement.break_label(), + loop_statement.break_label()); } else { __ jmp(&body); } PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); - __ bind(loop_statement.break_target()); + __ bind(loop_statement.break_label()); decrement_loop_depth(); } @@ -1102,7 +1142,7 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { // to introduce a new scope to bind the catch variable and to remove // that scope again afterwards. - Label try_handler_setup, catch_entry, done; + Label try_handler_setup, done; __ Call(&try_handler_setup); // Try handler code, exception in result register. @@ -1119,17 +1159,22 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { Scope* saved_scope = scope(); scope_ = stmt->scope(); ASSERT(scope_->declarations()->is_empty()); - Visit(stmt->catch_block()); + { WithOrCatch body(this); + Visit(stmt->catch_block()); + } scope_ = saved_scope; __ jmp(&done); // Try block code. Sets up the exception handler chain. __ bind(&try_handler_setup); { - TryCatch try_block(this, &catch_entry); + const int delta = StackHandlerConstants::kSize / kPointerSize; + TryCatch try_block(this); __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); + increment_stack_height(delta); Visit(stmt->try_block()); __ PopTryHandler(); + decrement_stack_height(delta); } __ bind(&done); } @@ -1161,6 +1206,7 @@ void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { // cooked before GC. Label finally_entry; Label try_handler_setup; + const int original_stack_height = stack_height(); // Setup the try-handler chain. Use a call to // Jump to try-handler setup and try-block code. Use call to put try-handler @@ -1169,9 +1215,9 @@ void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { // Try handler code. Return address of call is pushed on handler stack. { // This code is only executed during stack-handler traversal when an - // exception is thrown. The execption is in the result register, which + // exception is thrown. The exception is in the result register, which // is retained by the finally block. - // Call the finally block and then rethrow the exception. + // Call the finally block and then rethrow the exception if it returns. __ Call(&finally_entry); __ push(result_register()); __ CallRuntime(Runtime::kReThrow, 1); @@ -1182,6 +1228,7 @@ void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { // Finally block implementation. Finally finally_block(this); EnterFinallyBlock(); + set_stack_height(original_stack_height + Finally::kElementCount); Visit(stmt->finally_block()); ExitFinallyBlock(); // Return to the calling code. } @@ -1189,10 +1236,13 @@ void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { __ bind(&try_handler_setup); { // Setup try handler (stack pointer registers). + const int delta = StackHandlerConstants::kSize / kPointerSize; TryFinally try_block(this, &finally_entry); __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); + set_stack_height(original_stack_height + delta); Visit(stmt->try_block()); __ PopTryHandler(); + set_stack_height(original_stack_height); } // Execute the finally block on the way out. Clobber the unpredictable // value in the accumulator with one that's safe for GC. The finally @@ -1222,6 +1272,7 @@ void FullCodeGenerator::VisitConditional(Conditional* expr) { __ bind(&true_case); SetExpressionPosition(expr->then_expression(), expr->then_expression_position()); + int start_stack_height = stack_height(); if (context()->IsTest()) { const TestContext* for_test = TestContext::cast(context()); VisitForControl(expr->then_expression(), @@ -1235,6 +1286,7 @@ void FullCodeGenerator::VisitConditional(Conditional* expr) { PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); __ bind(&false_case); + set_stack_height(start_stack_height); if (context()->IsTest()) ForwardBailoutToChild(expr); SetExpressionPosition(expr->else_expression(), expr->else_expression_position()); @@ -1275,26 +1327,23 @@ void FullCodeGenerator::VisitSharedFunctionInfoLiteral( void FullCodeGenerator::VisitThrow(Throw* expr) { Comment cmnt(masm_, "[ Throw"); + // Throw has no effect on the stack height or the current expression context. + // Usually the expression context is null, because throw is a statement. VisitForStackValue(expr->exception()); __ CallRuntime(Runtime::kThrow, 1); + decrement_stack_height(); // Never returns here. } -int FullCodeGenerator::TryFinally::Exit(int stack_depth) { +FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit( + int* stack_depth, + int* context_length) { // The macros used here must preserve the result register. - __ Drop(stack_depth); - __ PopTryHandler(); - __ Call(finally_entry_); - return 0; -} - - -int FullCodeGenerator::TryCatch::Exit(int stack_depth) { - // The macros used here must preserve the result register. - __ Drop(stack_depth); + __ Drop(*stack_depth); __ PopTryHandler(); - return 0; + *stack_depth = 0; + return previous_; } |
