Revision: 3355 Author: [email protected] Date: Wed Nov 25 01:05:30 2009 Log: Fast-compiler: Add stack limit checks to back edges of while, do-while and for. A few other tweaks.
Review URL: http://codereview.chromium.org/435020 http://code.google.com/p/v8/source/detail?r=3355 Modified: /branches/bleeding_edge/src/arm/fast-codegen-arm.cc /branches/bleeding_edge/src/arm/macro-assembler-arm.cc /branches/bleeding_edge/src/arm/macro-assembler-arm.h /branches/bleeding_edge/src/fast-codegen.cc /branches/bleeding_edge/src/heap.h /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h /branches/bleeding_edge/src/x64/fast-codegen-x64.cc /branches/bleeding_edge/src/x64/macro-assembler-x64.cc /branches/bleeding_edge/src/x64/macro-assembler-x64.h ======================================= --- /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Fri Nov 13 01:51:49 2009 +++ /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Wed Nov 25 01:05:30 2009 @@ -376,26 +376,26 @@ __ mov(r0, Operand(Factory::the_hole_value())); if (FLAG_debug_code) { // Check if we have the correct context pointer. - __ ldr(r1, CodeGenerator::ContextOperand( - cp, Context::FCONTEXT_INDEX)); + __ ldr(r1, CodeGenerator::ContextOperand(cp, + Context::FCONTEXT_INDEX)); __ cmp(r1, cp); __ Check(eq, "Unexpected declaration in current context."); } __ str(r0, CodeGenerator::ContextOperand(cp, slot->index())); // No write barrier since the_hole_value is in old space. - ASSERT(Heap::InNewSpace(*Factory::the_hole_value())); + ASSERT(!Heap::InNewSpace(*Factory::the_hole_value())); } else if (decl->fun() != NULL) { Visit(decl->fun()); __ pop(r0); if (FLAG_debug_code) { // Check if we have the correct context pointer. - __ ldr(r1, CodeGenerator::ContextOperand( - cp, Context::FCONTEXT_INDEX)); + __ ldr(r1, CodeGenerator::ContextOperand(cp, + Context::FCONTEXT_INDEX)); __ cmp(r1, cp); __ Check(eq, "Unexpected declaration in current context."); } __ str(r0, CodeGenerator::ContextOperand(cp, slot->index())); - int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; + int offset = Context::SlotOffset(slot->index()); __ mov(r2, Operand(offset)); // We know that we have written a function, which is not a smi. __ RecordWrite(cp, r2, r0); ======================================= --- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Thu Nov 12 05:55:21 2009 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Wed Nov 25 01:05:30 2009 @@ -155,6 +155,15 @@ } +void MacroAssembler::StackLimitCheck(Label* on_stack_overflow) { + LoadRoot(ip, Heap::kStackLimitRootIndex); + cmp(sp, Operand(ip)); + b(lo, on_stack_overflow); +} + + + + void MacroAssembler::SmiJumpTable(Register index, Vector<Label*> targets) { // Empty the const pool. CheckConstPool(true, true); ======================================= --- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Thu Nov 12 05:55:21 2009 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Wed Nov 25 01:05:30 2009 @@ -78,6 +78,11 @@ // well as the ip register. void RecordWrite(Register object, Register offset, Register scratch); + // --------------------------------------------------------------------------- + // Stack limit support + + void StackLimitCheck(Label* on_stack_limit_hit); + // --------------------------------------------------------------------------- // Activation frames ======================================= --- /branches/bleeding_edge/src/fast-codegen.cc Fri Nov 13 01:42:18 2009 +++ /branches/bleeding_edge/src/fast-codegen.cc Wed Nov 25 01:05:30 2009 @@ -305,12 +305,15 @@ void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { Comment cmnt(masm_, "[ DoWhileStatement"); increment_loop_depth(); - Label body, exit; - - // Emit the test at the bottom of the loop. + Label body, exit, stack_limit_hit, stack_check_success; + __ bind(&body); Visit(stmt->body()); + // Check stack before looping. + __ StackLimitCheck(&stack_limit_hit); + __ bind(&stack_check_success); + // We are not in an expression context because we have been compiling // statements. Set up a test expression context for the condition. ASSERT_EQ(NULL, true_label_); @@ -322,6 +325,11 @@ true_label_ = NULL; false_label_ = NULL; + __ bind(&stack_limit_hit); + StackCheckStub stack_stub; + __ CallStub(&stack_stub); + __ jmp(&stack_check_success); + __ bind(&exit); decrement_loop_depth(); @@ -331,7 +339,7 @@ void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { Comment cmnt(masm_, "[ WhileStatement"); increment_loop_depth(); - Label test, body, exit; + Label test, body, exit, stack_limit_hit, stack_check_success; // Emit the test at the bottom of the loop. __ jmp(&test); @@ -340,6 +348,10 @@ Visit(stmt->body()); __ bind(&test); + // Check stack before looping. + __ StackLimitCheck(&stack_limit_hit); + __ bind(&stack_check_success); + // We are not in an expression context because we have been compiling // statements. Set up a test expression context for the condition. ASSERT_EQ(NULL, true_label_); @@ -351,6 +363,11 @@ true_label_ = NULL; false_label_ = NULL; + __ bind(&stack_limit_hit); + StackCheckStub stack_stub; + __ CallStub(&stack_stub); + __ jmp(&stack_check_success); + __ bind(&exit); decrement_loop_depth(); @@ -359,7 +376,7 @@ void FastCodeGenerator::VisitForStatement(ForStatement* stmt) { Comment cmnt(masm_, "[ ForStatement"); - Label test, body, exit; + Label test, body, exit, stack_limit_hit, stack_check_success; if (stmt->init() != NULL) Visit(stmt->init()); increment_loop_depth(); @@ -367,9 +384,15 @@ __ jmp(&test); __ bind(&body); Visit(stmt->body()); + + // Check stack before looping. + __ StackLimitCheck(&stack_limit_hit); + __ bind(&stack_check_success); + if (stmt->next() != NULL) Visit(stmt->next()); __ bind(&test); + if (stmt->cond() == NULL) { // For an empty test jump to the top of the loop. __ jmp(&body); @@ -378,6 +401,7 @@ // statements. Set up a test expression context for the condition. ASSERT_EQ(NULL, true_label_); ASSERT_EQ(NULL, false_label_); + true_label_ = &body; false_label_ = &exit; ASSERT(stmt->cond()->context() == Expression::kTest); @@ -385,6 +409,11 @@ true_label_ = NULL; false_label_ = NULL; } + + __ bind(&stack_limit_hit); + StackCheckStub stack_stub; + __ CallStub(&stack_stub); + __ jmp(&stack_check_success); __ bind(&exit); decrement_loop_depth(); ======================================= --- /branches/bleeding_edge/src/heap.h Tue Nov 24 06:10:06 2009 +++ /branches/bleeding_edge/src/heap.h Wed Nov 25 01:05:30 2009 @@ -880,7 +880,10 @@ static int linear_allocation_scope_depth_; static bool context_disposed_pending_; - static const int kMaxMapSpaceSize = 8*MB; + // The number of MapSpace pages is limited by the way we pack + // Map pointers during GC. + static const int kMaxMapSpaceSize = + (1 << MapWord::kMapPageIndexBits) * Page::kPageSize; #if defined(V8_TARGET_ARCH_X64) static const int kMaxObjectSizeInNewSpace = 512*KB; ======================================= --- /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc Fri Nov 13 05:59:07 2009 +++ /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc Wed Nov 25 01:05:30 2009 @@ -380,6 +380,7 @@ } __ mov(CodeGenerator::ContextOperand(esi, slot->index()), eax); // No write barrier since the_hole_value is in old space. + ASSERT(!Heap::InNewSpace(*Factory::the_hole_value())); } else if (decl->fun() != NULL) { Visit(decl->fun()); __ pop(eax); @@ -391,7 +392,7 @@ __ Check(equal, "Unexpected declaration in current context."); } __ mov(CodeGenerator::ContextOperand(esi, slot->index()), eax); - int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; + int offset = Context::SlotOffset(slot->index()); __ RecordWrite(esi, offset, eax, ecx); } break; ======================================= --- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Fri Nov 13 04:32:57 2009 +++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Wed Nov 25 01:05:30 2009 @@ -211,6 +211,13 @@ bind(&done); } + + +void MacroAssembler::StackLimitCheck(Label* on_stack_overflow) { + cmp(esp, + Operand::StaticVariable(ExternalReference::address_of_stack_limit())); + j(below, on_stack_overflow); +} #ifdef ENABLE_DEBUGGER_SUPPORT ======================================= --- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Fri Nov 6 03:35:47 2009 +++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Wed Nov 25 01:05:30 2009 @@ -68,6 +68,12 @@ RegList regs); #endif + // --------------------------------------------------------------------------- + // Stack limit support + + // Do simple test for stack overflow. This doesn't handle an overflow. + void StackLimitCheck(Label* on_stack_limit_hit); + // --------------------------------------------------------------------------- // Activation frames ======================================= --- /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Fri Nov 13 01:42:18 2009 +++ /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Wed Nov 25 01:05:30 2009 @@ -382,26 +382,26 @@ __ Move(rax, Factory::the_hole_value()); if (FLAG_debug_code) { // Check if we have the correct context pointer. - __ movq(rbx, CodeGenerator::ContextOperand( - rsi, Context::FCONTEXT_INDEX)); + __ movq(rbx, CodeGenerator::ContextOperand(rsi, + Context::FCONTEXT_INDEX)); __ cmpq(rbx, rsi); __ Check(equal, "Unexpected declaration in current context."); } __ movq(CodeGenerator::ContextOperand(rsi, slot->index()), rax); // No write barrier since the_hole_value is in old space. - ASSERT(Heap::InNewSpace(*Factory::the_hole_value())); + ASSERT(!Heap::InNewSpace(*Factory::the_hole_value())); } else if (decl->fun() != NULL) { Visit(decl->fun()); __ pop(rax); if (FLAG_debug_code) { // Check if we have the correct context pointer. - __ movq(rbx, CodeGenerator::ContextOperand( - rsi, Context::FCONTEXT_INDEX)); + __ movq(rbx, CodeGenerator::ContextOperand(rsi, + Context::FCONTEXT_INDEX)); __ cmpq(rbx, rsi); __ Check(equal, "Unexpected declaration in current context."); } __ movq(CodeGenerator::ContextOperand(rsi, slot->index()), rax); - int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; + int offset = Context::SlotOffset(slot->index()); __ RecordWrite(rsi, offset, rax, rcx); } break; ======================================= --- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Tue Nov 17 00:35:43 2009 +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Wed Nov 25 01:05:30 2009 @@ -65,6 +65,12 @@ LoadRoot(kScratchRegister, index); cmpq(with, kScratchRegister); } + + +void MacroAssembler::StackLimitCheck(Label* on_stack_overflow) { + CompareRoot(rsp, Heap::kStackLimitRootIndex); + j(below, on_stack_overflow); +} static void RecordWriteHelper(MacroAssembler* masm, ======================================= --- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Wed Nov 4 00:51:48 2009 +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Wed Nov 25 01:05:30 2009 @@ -97,6 +97,12 @@ RegList regs); #endif + // --------------------------------------------------------------------------- + // Stack limit support + + // Do simple test for stack overflow. This doesn't handle an overflow. + void StackLimitCheck(Label* on_stack_limit_hit); + // --------------------------------------------------------------------------- // Activation frames --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
